Migrate Swift projects to 6.2 concurrency with default single-thread execution, explicit @concurrent background unloading, and MainActor isolation consistency for data race safety.
How this skill is triggered — by the user, by Claude, or both
Slash command
/everything-claude-code:swift-concurrency-6-2The summary Claude sees in its skill listing — used to decide when to auto-load this skill
采用 Swift 6.2 并发模型的模式,代码默认单线程执行,并发需要显式引入。在不牺牲性能的情况下消除常见的数据竞争错误。
采用 Swift 6.2 并发模型的模式,代码默认单线程执行,并发需要显式引入。在不牺牲性能的情况下消除常见的数据竞争错误。
在 Swift 6.1 及更早版本中,async 函数可能被隐式卸载到后台线程,导致即使看似安全的代码也会出现数据竞争错误:
// Swift 6.1: 错误
@MainActor
final class StickerModel {
let photoProcessor = PhotoProcessor()
func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
guard let data = try await item.loadTransferable(type: Data.self) else { return nil }
// 错误:发送 'self.photoProcessor' 存在数据竞争风险
return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
}
}
Swift 6.2 修复了这个问题:async 函数默认留在调用者的 Actor 上。
// Swift 6.2: 正确 — async 留在 MainActor 上,没有数据竞争
@MainActor
final class StickerModel {
let photoProcessor = PhotoProcessor()
func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
guard let data = try await item.loadTransferable(type: Data.self) else { return nil }
return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
}
}
MainActor 类型现在可以安全地遵循非隔离协议:
protocol Exportable {
func export()
}
// Swift 6.1: 错误 — 跨越到主 Actor 隔离的代码
// Swift 6.2: 通过隔离一致性解决
extension StickerModel: @MainActor Exportable {
func export() {
photoProcessor.exportAsPNG()
}
}
编译器确保一致性只在主 Actor 上使用:
// 正确 — ImageExporter 也是 @MainActor
@MainActor
struct ImageExporter {
var items: [any Exportable]
mutating func add(_ item: StickerModel) {
items.append(item) // 安全:相同的 Actor 隔离
}
}
// 错误 — 非隔离上下文不能使用 MainActor 一致性
nonisolated struct ImageExporter {
var items: [any Exportable]
mutating func add(_ item: StickerModel) {
items.append(item) // 错误:主 Actor 隔离的一致性不能在此使用
}
}
使用 MainActor 保护全局/静态状态:
// Swift 6.1: 错误 — 非 Sendable 类型可能有共享可变状态
final class StickerLibrary {
static let shared: StickerLibrary = .init() // 错误
}
// 修复:使用 @MainActor 标注
@MainActor
final class StickerLibrary {
static let shared: StickerLibrary = .init() // 正确
}
Swift 6.2 引入了一种模式,MainActor 默认被推断 — 不需要手动标注:
// 启用 MainActor 默认推断后:
final class StickerLibrary {
static let shared: StickerLibrary = .init() // 隐式 @MainActor
}
final class StickerModel {
let photoProcessor: PhotoProcessor
var selection: [PhotosPickerItem] // 隐式 @MainActor
}
extension StickerModel: Exportable { // 隐式 @MainActor 一致性
func export() {
photoProcessor.exportAsPNG()
}
}
此模式是可选的,推荐用于应用、脚本和其他可执行目标。
当你需要真正的并行性时,使用 @concurrent 显式卸载:
重要: 此示例需要 Approachable Concurrency 构建设置 — SE-0466(MainActor 默认隔离)和 SE-0461(NonisolatedNonsendingByDefault)。启用这些设置后,
extractSticker留在调用者的 Actor 上,使可变状态访问安全。没有这些设置,此代码存在数据竞争 — 编译器会标记它。
nonisolated final class PhotoProcessor {
private var cachedStickers: [String: Sticker] = [:]
func extractSticker(data: Data, with id: String) async -> Sticker {
if let sticker = cachedStickers[id] {
return sticker
}
let sticker = await Self.extractSubject(from: data)
cachedStickers[id] = sticker
return sticker
}
// 将昂贵的工作卸载到并发线程池
@concurrent
static func extractSubject(from data: Data) async -> Sticker { /* ... */ }
}
// 调用者必须 await
let processor = PhotoProcessor()
processedPhotos[item.id] = await processor.extractSticker(data: data, with: item.id)
使用 @concurrent 的步骤:
nonisolated@concurrentasyncawait| 决策 | 理由 |
|---|---|
| 默认单线程 | 最自然的代码是数据竞争自由的;并发是可选的 |
| Async 留在调用 Actor 上 | 消除导致数据竞争错误的隐式卸载 |
| 隔离一致性 | MainActor 类型可以遵循协议而无需不安全的变通方案 |
@concurrent 显式选择加入 | 后台执行是刻意的性能选择,而非意外的 |
| MainActor 默认推断 | 减少应用目标的样板 @MainActor 标注 |
| 可选采用 | 非破坏性迁移路径 — 逐步启用功能 |
SwiftSettings API@concurrent:先分析,再卸载热路径@concurrent — 图像处理、压缩、复杂计算nonisolated 变通方案或 @Sendable 包装器@concurrent(大多数不需要后台执行)nonisolated 来抑制编译器错误而不理解隔离DispatchQueue 模式model.availability 检查npx claudepluginhub aaione/everything-claude-code-zhGuides Swift 6.2 Approachable Concurrency: default single-threaded async execution, explicit @concurrent offloading, MainActor isolation for data-race prevention and protocol conformances.
Patterns for adopting Swift 6.2's approachable concurrency model: single-threaded by default, @concurrent for explicit background offloading, and isolated conformances for MainActor types.
Fixes Swift concurrency compiler errors, adopts approachable concurrency (SE-0466), and writes data-race-safe async code. Use when resolving Sendable conformance errors, actor isolation warnings, or migrating to Swift 6 strict concurrency.