在 SwiftUI 并发模型(尤其是 Swift 5.5+),有些类或初始化方法被标记为只能在主线程中使用。
例如 UIKit / SwiftUI 相关对象的初始化:
@MainActor init(...)
如果在非主线程的上下文中,调用被标记为 @MainActor 的初始化方法,就会报错。
例如:
func fetchData() {
Task {
let summary = try await HKActivitySummaryQuery(includeSampleMoments: true) // 假设这个 init 有 @MainActor
}
}
因为 Task {} 默认运行在非主线程上,所以Xcode会报错:
Call to main actor-isolated initializer 'init(includeSampleMoments:)' in a synchronous nonisolated context
解决方案
方案1、在主 actor上调用
如果该初始化确实需要在主线程上执行(比如 UI 或系统对象),用 @MainActor 包裹调用:
Task { @MainActor in
let summary = HKActivitySummaryQuery(includeSampleMoments: true)
}
或者显式地切到主线程:
Task {
await MainActor.run {
let summary = HKActivitySummaryQuery(includeSampleMoments: true)
}
}
方案2、让调用者称为主 actor
如果在某个类的方法中调用,而这个类本身是 UI 相关,可以直接声明:
@MainActor
class SomeViewModel {
func loadData() {
let summary = HKActivitySummaryQuery(includeSampleMoments: true)
}
}
这样整个方法都自动在主 actor 上运行,不再报错。
总结
标记为 @MainActor 的初始化,都必须在主线程中创建。
Task { @MainActor in
let summary = HKActivitySummaryQuery(includeSampleMoments: true)
}
