When I try to define an actor
that conforms to a protocol
, Xcode gives me the error Actor-isolated instance method 'foo()' cannot be used to satisfy nonisolated protocol requirement
. I can make the func nonisolated
I don't think I want to. Do I need to? What would I be losing if I do so?
Here's the example code that causes the error:
protocol Fooable {
func foo() -> Int
}
actor Bar: Fooable { // Error: Actor-isolated instance method...
func foo() -> Int {
return 42
}
}
If you tap on the “auto fix” button in front of the error message it will expand to show you two options:
In short, you can either:
Add nonisolated
to foo()
to make this instance method not isolated to the actor:
protocol Fooable {
func foo() -> Int
}
actor Bar: Fooable {
nonisolated func foo() -> Int {
return 42
}
}
Mark the protocol requirement foo()
async
to allow actor-isolated conformance:
protocol Fooable {
func foo() async -> Int
}
actor Bar: Fooable {
func foo() -> Int {
return 42
}
}
This is not an option that the auto-fix options include, but you can isolate the protocol to a global actor, such as the MainActor
. Types that conform to that protocol must/will be isolated to the same global actor, though.
@MainActor
protocol Fooable {
func foo() -> Int
}
class Bar: Fooable { // this protocol requirement isolates `Bar` to the same global actor as `Fooable`, i.e., `MainActor` in this case
func foo() -> Int {
return 42
}
}
This is the pattern adopted by many standard Apple protocols. E.g., UITableViewDataSource
is isolated to the main actor.
In short, an isolated method cannot be used to satisfy a nonisolated requirement.
You asked whether you could use nonisolated
:
What would I be losing if I do so?
If it is nonisolated
, the method simply cannot directly access actor-isolated properties nor call actor-isolated methods. As the method currently stands, you can safely make it nonisolated
.
In short, if a method does not require actor-isolation, you should generally feel free to mark it as nonisolated
.