In Objective-c we can use NS_SWIFT_UI_ACTOR
to indicate that a method or a whole class should be executed on the main actor (as we would do with @MainActor
in Swift). This works correctly since, when invoking a method which returns a value from outside the main actor (using a Task.detached with background priority), the compiler forces us to call it using "await" (to allow for "actor switch") and, at runtime, I can see that the code is executed on the main thread.
However, when calling a callback based method on the same class (which gets an automatically "imported" async variant, as explained here ) the NS_SWIFT_UI_ACTOR seems not working properly, and the code is executed on a background thread.
NS_SWIFT_UI_ACTOR
@interface ObjcClass : NSObject
- (NSString *)method1;
- (void)method2WithCompletion: (void (^)(NSString * _Nonnull))completion;
@end
Task.detached(priority: .background) {
let objcInstance = ObjcClass()
print(await objcInstance.method1()) <----- this is called on the main thread
print(await objcInstance.method2()) <----- this is called on a bg thread
}
While I understand what your expectation is I don't think as of now the way actor is implemented there is any way to resolve this. Actors in swift are reentrant, which means whenever you invoke any async
method inside actor's method/actor task, actor suspends the current task until the method returns and starts processing other tasks. This reentrancy behavior is important as it doesn't just lock the actor when executing a long-running task.
Let's take an example of a MainActor
isolated async
method:
func test() async {
callSync() // Runs on MainActor
await callAsync() // Suspends to process other task, waits for return to resume executing on MainActor
callSync() // Runs on MainActor
}
But since swift can't infer from an objective c async
method which part should run on MainActor
and for which part actor can just suspend the current task to process other tasks, the entire async
method isn't isolated to the actor.
However, there are proposals currently to allow customizing an actor's reentrancy so you might be able to execute the entire objc async
method on the actor.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.