在Swif 6中,如果在非MainActor的同步上下文中,直接调用MainActor隔离的方法。
例如,在@MainActor标注的类中,add方法返回的闭包是同步上下文,闭包调用
Xcode就会提示:
@MainActor
class FileProcessingService: ObservableObject {
// 被调用的方法
private func createCustomImages(url: URL) -> CustomImages { }
func onDrop(type: WorkspaceType,providers:[NSItemProvider]) async {
wait withTaskGroup(of: CustomImages?.self) { group in
// addTask 闭包非 MainActor,处于非隔离(nonisolated)上下文
group.addTask {
provider.loadFileRepresentation(forTypeIdentifier: UTType.image.identifier) { loadUrl, error in
let customImages = self.createCustomImages(url: url) // 提示 Call to main...
cont.resume(returning: customImages)
}
}
}
}
}
完整提示:
Call to main actor-isolated instance method … in a synchronous nonisolated context; this is an error in the Swift 6 language mode
提示信息表示,在一个非MainActor的同步上下文中,直接调用了一个MainActor隔离的方法。
因为Swift 6要求调用MainActor方法时,需要显式标注MainActor方法。
解决方案
1、移除类级别的@MainActor
@MainActor
class FileProcessingService: ObservableObject { }
如果类中的属性和方法,大部分不需要在主线程上运行,可以移除类级别的@MainActor。
移除后,调用方法不会再因为MainActor隔离,弹出提示。
2、添加nonisolated关键字
如果@MainActor中的方法希望从外部调用,可以使用nonisolated修饰符。
@MainActor
class FileProcessingService: ObservableObject {
// 添加 nonisolated 修饰符
nonisolated private func createCustomImages(url: URL) -> CustomImages { }
}
被标记为nonisolated的方法,可以直接同步调用,不需要使用await。
