关于 swift_concurrency
这是一份 Swift 并发技能指南,面向编写异步代码或迁移到 Swift 6 的开发者。它讲解 async/await、结构化并发、Actor 隔离和严格并发检查,并提供迁移清单与实践建议。
主要功能
- 01讲解 async/await 与 Task
- 02介绍结构化并发和任务组
- 03说明 Actor、隔离与 Sendable
- 04涵盖 Swift 6 严格并发检查
- 05提供迁移清单和常见错误处理
适用场景
- 01将完成处理器改写为 async/await
- 02并行执行多个异步操作
- 03保护共享状态并处理数据竞争
- 04逐步迁移项目到 Swift 6
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ swiftzilla/ skills --skill swift_concurrency安装后在 Claude Code 中输入/swift_concurrency确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/swift6_strict_mode.mdasync_await.mdsendable.mdisolation.md详细介绍
Swift 并发
本技能涵盖 Swift 5.5 至 Swift 6 的现代并发功能,包括 async/await、结构化并发、actor,以及 Swift 6 的严格数据竞争安全性。
概览
Swift 的现代并发模型提供了一种更安全、更直观的异步代码编写方式。Swift 6 更进一步,实现了编译时数据竞争安全性,将潜在的并发错误转化为编译器错误。
可用参考资料
Swift 6 与严格并发
- Swift 6 严格模式 - 完整的并发检查,防止数据竞争
- Sendable 协议 - Sendable 一致性、@Sendable 闭包、线程安全
- 隔离与 Actors - @MainActor、全局 actor、基于区域的隔离
核心并发功能
- Async/Await - 异步函数、Task、TaskGroup、Actor 基础知识
Swift 6 重点
默认启用严格并发
Swift 6 在编译时强制保证数据竞争安全:
// ❌ Compile-time error in Swift 6
var globalCounter = 0
func increment() {
globalCounter += 1 // Error: concurrent access
}
// ✅ Safe with actor isolation
actor Counter {
private var value = 0
func increment() { value += 1 }
}
Sendable 协议
标记可在并发边界间安全共享的类型:
struct User: Sendable {
let id: Int
let name: String
}
@Sendable func process() async {
// Captures must be Sendable
}
MainActor 与全局 Actors
@MainActor
class ViewModel: ObservableObject {
@Published var items = [Item]()
}
@globalActor
actor DatabaseActor {
static let shared = DatabaseActor()
private init() {}
}
快速参考
Async/Await 基础知识
func fetchData() async throws -> Data {
let (data, _) = try await URLSession.shared.data(from: url)
return data
}
Swift 6 迁移清单
- 启用 Swift 6 语言模式
- 启用严格并发检查
- 使用 actors 封装全局可变状态
- 为类型添加 Sendable 一致性
- 修复 @Sendable 闭包中捕获的非 Sendable 值
- 使用 @MainActor 隔离 UI 代码
- 审查第三方依赖项
运行异步代码
// Fire-and-forget
Task {
let result = await asyncOperation()
}
// With priority
Task(priority: .background) {
await heavyComputation()
}
// With cancellation
let task = Task {
try await longRunningOperation()
}
task.cancel()
并发操作
// Async let (parallel await)
async let task1 = fetchUser()
async let task2 = fetchSettings()
let (user, settings) = try await (task1, task2)
// TaskGroup
try await withThrowingTaskGroup(of: Item.self) { group in
for id in ids {
group.addTask { try await fetchItem(id: id) }
}
return try await group.reduce(into: []) { $0.append($1) }
}
Actor 线程安全
actor BankAccount {
private var balance: Double = 0
func deposit(_ amount: Double) {
balance += amount
}
func getBalance() -> Double {
return balance
}
}
let account = BankAccount()
await account.deposit(100)
隔离边界
// Crossing isolation boundaries
@MainActor
func updateUI() async {
// On main thread
let data = await fetchData() // Switch to non-isolated
label.text = data // Back to main thread
}
// Region transfer
func process() async {
let data = Data() // Disconnected
await save(data) // Transfer to actor
// ❌ Can't use data here anymore
}
Swift 6 与 Swift 5.x 对比
| 功能 | Swift 5.x | Swift 6 |
|---|---|---|
| 并发检查 | 警告 | 错误 |
| 数据竞争安全性 | 运行时 | 编译时 |
| Sendable 强制检查 | 可选启用 | 必需 |
| 全局变量安全性 | 警告 | 错误 |
| 严格模式 | 实验性 | 默认启用 |
最佳实践
Swift 6 最佳实践
- 尽早启用 Swift 6 模式 - 立即开始迁移
- 使用 actors 管理共享状态 - 默认使用 actors,而非锁
- 设计 Sendable 类型 - 从一开始就让类型符合 Sendable
- 使用 @MainActor 隔离 UI - 所有 UI 代码都在主线程上运行
- 遵守隔离区域规则 - 转移值后不要再使用
- 善用编译时安全检查 - 让编译器捕获数据竞争
- 创建领域 actor - 为繁重工作创建自定义全局 actor
通用并发实践
- 优先使用 async/await - 而非完成处理器
- 使用结构化并发 - 明确任务层级
- 处理取消操作 - 检查 Task.isCancelled
- 使用值类型 - 不可变数据是线程安全的
- 避免共享可变状态 - 或使用 actors 保护状态
从完成处理器迁移
// Before (Swift 5)
func fetchUser(completion: @escaping (Result<User, Error>) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
// Handle result
completion(result)
}.resume()
}
// After (Swift 6)
func fetchUser() async throws -> User {
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode(User.self, from: data)
}
常见 Swift 6 错误
| 错误 | 快速修复方法 |
|---|---|
| 对全局变量的并发访问 | 使用 actor 封装 |
| @Sendable 中包含非 Sendable 值 | 让类型符合 Sendable |
| Actor 隔离违规 | 添加 await 或更改隔离方式 |
| 转移后使用值 | 在转移前使用,或复制值 |
| 主 actor 隔离 | 添加 @MainActor 注解 |
资源
- Swift Evolution: https://github.com/apple/swift-evolution
- SE-0412: 全局变量的严格并发检查
- SE-0471: SerialExecutor 隔离检查
- SE-0430: 发送参数
- SE-0414: 基于区域的隔离
- Apple 文档: https://developer.apple.com/documentation/swift/concurrency
- SwiftZilla: https://swiftzilla.dev
更多信息
每个参考文件都包含特定主题的详细信息、代码示例和最佳实践。访问 https://swiftzilla.dev,查看全面的 Swift 并发文档。
评论
支持 Markdown