Skip to content

Swift 入门(20):并发与异步

Swift 从 5.5 开始引入了现代化的 并发模型,主要包括 async/awaitTask、以及 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 封装成异步。

本站总访问