I have an actor protocol declared like this:
protocol MyActorProtocol: Actor {
func foo()
}
There’s an actor which conforms to the protocol:
actor MyImplementation1: MyActorProtocol {
func foo() {}
}
Now I need to add a proxy:
actor MyImplementation1Proxy: MyActorProtocol {
let impl: MyActorProtocol
init(impl: MyActorProtocol) {
self.impl = impl
}
func foo() {
// Error-1: Call to actor-isolated instance method 'foo()' in a synchronous actor-isolated context
// impl.foo()
// Error-2. 'await' in a function that does not support concurrency
// await impl.foo()
// Success-3. only this passes the compiler check
Task { await impl.foo() }
}
}
I want to understand such points:
- Why is it possible for actor protocol to have non-async methods declared, without an explicit
nonisolated
keyword? - Let’s say it’s possible to have non-async methods, then why would I ever have
Error-1
in my code? - Given
MyImplementation1Proxy
also conforms toMyActorProtocol
, andMyImplementation1.foo
must be called inTask
(for whatever reason), then it feelsMyImplementation1.foo
is “kind of async”, soMyImplementation1Proxy.foo
should have this “kind of async context” as well, so why do I haveError-2
? - From
Error-2
looks like the method is just “non async”, but when I tried to introduce a non-actor implementation, gotCall to actor-isolated instance method 'foo()' in a synchronous nonisolated context
, which is fair but again leads to question 1:
class MyImplementation2 {
let impl: MyActorProtocol
init(impl: MyActorProtocol) {
self.impl = impl
}
func bar() {
impl.foo()
}
}
Thanks in advance.