Reputation: 16598
Let's say we have the following goals:
So the specific question is: How can we conform a Swift actor to a protocol while preserving isolation?
protocol Zippity {
func foo()
}
actor Zappity: Zippity {
func foo() {} // Doesn't compile
}
I can make it compile with …
actor Zappity: Zippity {
nonisolated func foo() {}
}
… but that seems to defeat the purpose. I also tried declaring the interface method async
but that also didn't compile.
I can think of several reasonable workarounds, including composition, nonisolated async
methods that call isolated methods, etc. but wanted to see if there's something I'm missing.
Upvotes: 20
Views: 6679
Reputation: 118
Actors are only able to be thread safe by making all their functions implicitly async. It does some magic behind the curtains, to make sure it’s being called in the right thread.
To fix this you can either inherit from Actor on the protocol
protocol Foo: Actor {
func bar()
}
Or mark the functions async
protocol Foo {
func bar() async
}
Upvotes: 2
Reputation: 3804
As long as the protocol does not use property setters, marking every method and property getter as async will let an actor conform to the protocol. As it is not possible to have async setters, conformance to Actor
is needed in that case.
So in your example:
protocol Zippity {
func foo() async
}
Upvotes: 1
Reputation: 16598
OK, I've discovered the answer, and it's pretty straightforward:
protocol Zippity: Actor {
func foo()
}
actor Zappity: Zippity {
func foo() // This is a properly isolated method
}
It seems that declaring conformity to the Actor
protocol enables the compiler magic.
Upvotes: 44