somu
(somu)
1
Hi,
In Build Settings when I set Strict Concurrency Checking to Complete and compile the code below I get a warning.
Warning:
Non-sendable type 'Logger' in conformance of main actor-isolated property 'logger' to protocol requirement cannot cross actor boundary
Code:
import Foundation
import os
protocol P1 {
var logger: Logger { get }
}
@MainActor
class Model: P1 {
//Warning: Non-sendable type 'Logger' in conformance of main actor-isolated property 'logger' to protocol requirement cannot cross actor boundary
let logger = Logger(subsystem: "sys1",category: "cat1")
}
Build Setting
- In Build Settings set
Strict Concurrency Checking to Complete
Questions:
- What should I do to resolve this warning?
- Or is this a bug in the
os framework?
My Observation
- Instead of
@MainActor class if I used actor, then I could resolve the issue by adding a requirement that P1 must conform to Actor however I am not sure what must be done for @MainActor
somu
(somu)
2
Looks like if there is a @MainActor conforming to the protocol we could do on elf the options:
Option 1 (If main actor needs to be applied to the entire protocol)
@MainActor
protocol P1 {
var logger: Logger { get }
}
Option 2 (If main actor needs to be applied only to one property)
protocol P1 {
@MainActor var logger: Logger { get }
}
Note:
- Looks like
Actor is a protocol that can be used if we have a protocol that is conformed by actors.
- Looks like
@MainActor doesn't conform to Actor and hence we need to apply the attribute @MainActor
Another option is:
@MainActor
class Model: P1 {
nonisolated let logger = Logger(subsystem: "sys1",category: "cat1")
}
The nonisolated modifier means that P1.logger is not isolated to the main actor like the rest of the class. This is required to fulfill the protocol requirement, which has no indication of actor isolation.
As you mention, another way to solve this issue is to make the requirement isolated, which you achieved both implicitly through @MainActor protocol P1 and explicitly @MainActor var logger. In this case, you isolate to the provided MainActor.
Lastly, actors have implicit isolation (to themselves). Writing actor Model { var logger: Logger } means you're allowed to access logger synchronously only within the actor Model. Because you (again) deal with isolation, you must somehow indicate that in your protocol. By writing P1: Actor you're saying that every protocol requirement is implicitly isolated to the Self actor.
I know this discussion of isolated, implicit isolated, and non-isolated can be confusing but I hope I helped. Let me know if anything was unclear.
3 Likes
somu
(somu)
4
Thanks a lot @filip-sakel for showing the non-isolated option
Yeah it is a bit tricky but I am slowly starting to understand, thanks!
1 Like