1. 异步函数和 async/await
async
表示函数是异步的,可以执行一些耗时操作而不阻塞线程。await
用来等待异步操作的完成。它让代码看起来像是同步的,但实际上在异步执行。
Swift
func fetchData() async -> String {
// 模拟网络请求
return "Data from server"
}
func processData() async {
let data = await fetchData()
print(data) // 输出: Data from server
}
2. 任务和任务组
Task
代表一个异步操作。Task
可以是单独的任务,也可以组成 TaskGroup
进行并行执行。
特性
-
TaskGroup
提供了一种简单的方式来管理多个并发任务。 -
Task
和TaskGroup
都可以自动管理生命周期,避免内存泄漏。
Task
来启动一个新的异步任务:
Swift
Task {
let data = await fetchData()
print(data)
}
任务组
TaskGroup
可以让多个任务并行执行并等待它们的结果:
Swift
func fetchMultipleData() async {
await withTaskGroup(of: String.self) { group in
group.addTask {
await fetchData()
}
group.addTask {
await fetchData()
}
for await result in group {
print(result) // 依次输出每个任务的结果
}
}
}
3. Actor:数据隔离
特性
-
Actor
自动保证线程安全,不需要手动加锁。 -
适合在并发环境中管理共享状态。
Actor
用来确保对共享状态的安全访问。Actor
提供了一种更简单的数据同步机制,避免传统锁(locks)带来的复杂性。
Swift
actor Counter {
private var value = 0
func increment() {
value += 1
}
func getValue() -> Int {
return value
}
}
let counter = Counter()
Task {
await counter.increment()
print(await counter.getValue()) // 输出: 1
}
4. 结构化并发
特性
-
通过
async let
语法启动异步任务,并确保所有任务在作用域结束时完成。 -
避免资源泄漏和悬空任务。
确保所有异步任务在作用域结束前都能被正确完成。使用 async
函数创建的任务,通常是结构化的,意味着任务有明确的作用域和生命周期。
Swift
func structuredConcurrencyExample() async {
async let data1 = fetchData()
async let data2 = fetchData()
let combinedData = await "\(data1), \(data2)"
print(combinedData)
}
5.取消任务
Swift 的并发任务可以取消。任务需要自己检查是否已取消,以便优雅地终止。
特性
- 任务取消是协作式的,任务需要定期检查
Task.isCancelled
以响应取消请求。 TaskGroup
中的任务取消也会自动取消所有子任务。
Swift
func cancellableTask() async {
for i in 1...10 {
if Task.isCancelled {
print("任务已取消")
return
}
print(i)
try? await Task.sleep(nanoseconds: 500_000_000) // 延迟 0.5 秒
}
}
let task = Task {
await cancellableTask()
}
// 取消任务
task.cancel()
6.非阻塞的延迟:Task.sleep
特性
-
适合在任务之间插入非阻塞的延迟。
-
替代了传统的
sleep
,不会阻塞主线程。
Task.sleep
是一种异步延迟机制,让任务可以暂停一段时间而不阻塞线程。它以纳秒为单位。
Swift
func exampleDelay() async {
print("Start")
try? await Task.sleep(nanoseconds: 2 * 1_000_000_000) // 延迟 2 秒
print("End")
}