Appearance
Swift 入门(20):并发与异步
Swift 从 5.5 开始引入了现代化的 并发模型,主要包括
async/await、Task、以及Actor。它让异步代码更直观,也避免了回调地狱。
1. async/await 基础
用 async 标记异步函数,用 await 调用它。
swift
func fetchData() async -> String {
return "数据结果"
}
Task {
let result = await fetchData()
print(result)
}2. 异步任务 Task
Task {} 可以在任何地方开启一个并发任务。
swift
Task {
print("开始下载")
let data = await fetchData()
print("下载完成: \(data)")
}3. 并发执行
多个异步任务可以 并发执行。
swift
func task1() async -> String {
try? await Task.sleep(nanoseconds: 1_000_000_000)
return "任务1完成"
}
func task2() async -> String {
return "任务2完成"
}
Task {
async let r1 = task1()
async let r2 = task2()
print(await r1, await r2)
}4. 异步序列
异步版本的 for-in,用于流式数据。
swift
func numbers() -> AsyncStream<Int> {
AsyncStream { continuation in
for i in 1...3 {
continuation.yield(i)
}
continuation.finish()
}
}
Task {
for await num in numbers() {
print(num)
}
}5. Actor(解决共享数据并发问题)
Actor 用来保证数据的 线程安全。
swift
actor Counter {
var value = 0
func increment() { value += 1 }
}
let counter = Counter()
Task {
await counter.increment()
print(await counter.value)
}6. 与传统回调互操作
老的 回调 API 可以通过 withCheckedContinuation 转成 async。
swift
func loadData(completion: @escaping (String) -> Void) {
DispatchQueue.global().async {
completion("旧API数据")
}
}
func loadDataAsync() async -> String {
await withCheckedContinuation { cont in
loadData { result in cont.resume(returning: result) }
}
}
Task {
print(await loadDataAsync())
}总结
async/await让异步代码像同步一样易读。Task开启并发任务,async let并发执行多个任务。Actor提供线程安全的数据访问。- 旧回调 API 可以用
Continuation封装成异步。