tva
← Insights

Swift 6 并发:实用迁移指南

Swift 6 改变了什么

Swift 5.x 对并发违规发出警告。Swift 6 将其变成了错误。这意味着可能包含数据竞争的代码在 Swift 6 下无法编译——即使该代码在实践中从未产生竞争。编译器保守地将模糊情况视为错误。

最常见的迁移问题

主线程 UI 更新:在后台任务中从非隔离上下文更新 UI 属性:

// Swift 5 - 警告
func loadData() async {
    let result = await fetchData()
    self.items = result // 可能不在主线程
}

// Swift 6 - 修复
func loadData() async {
    let result = await fetchData()
    await MainActor.run {
        self.items = result
    }
}

跨 actor 的 Sendable 违规:将非 Sendable 类型传递给异步上下文:

// 将类标记为 Sendable 或使其 actor 隔离
final class DataModel: @unchecked Sendable {
    // 手动保证线程安全
}

迁移策略

不要试图一次性修复所有警告。使用分阶段方法:首先让项目在 Swift 6 下编译,使用 @preconcurrency 来抑制尚未准备好修复的警告,然后逐模块解决实际的并发违规。

@preconcurrency import 对于还没有更新到 Swift 6 的第三方库特别有用。

Actor 隔离实践

@MainActor 标注视图模型,以确保所有属性更新都在主线程上:

@MainActor
class ViewModel: ObservableObject {
    @Published var items: [Item] = []

    func load() async {
        items = await fetchItems() // 自动在主线程
    }
}

相关洞见

相关文章