并发编程

Swift 5.5 起,Swift 引入了强大的原生并发模型,基于 Structured Concurrency(结构化并发)Actor 模型,极大提升了异步代码的可读性和安全性。


🔑 1. Swift 并发的核心组件 #

组件作用关键词
async / await异步函数的定义与调用,简化回调地狱asyncawait
Task创建异步任务,支持并发执行Task {}
TaskGroup / withTaskGroup并发任务组,批量任务的并发控制withTaskGroup
Actor保证数据访问的线程安全,避免竞争条件actor
@MainActor强制代码在主线程执行,适用于 UI 更新@MainActor
DetachedTask脱离父任务的异步任务,适合独立后台任务DetachedTask {}
AsyncSequence异步数据流处理,适合流式数据和事件监听for await in
Continuation与传统回调机制互操作,支持逃逸闭包转换成异步调用CheckedContinuation
Sendable标记类型在并发环境中是线程安全的@Sendable

🌟 2. async / await:现代异步的基石 #

✅ 基础用法: #

func fetchData() async -> String {
    // 模拟异步网络请求
    try? await Task.sleep(nanoseconds: 1_000_000_000)
    return "数据加载完成"
}

Task {
    let data = await fetchData()
    print(data)  // 输出:数据加载完成
}
  • async:声明异步函数。
  • await:等待异步操作完成,不阻塞线程,代码仍然顺序执行。

3. Task:轻量级并发任务 #

🚀 创建任务: #

Task {
    let result = await fetchData()
    print(result)
}

🚀 取消任务: #

let task = Task {
    try Task.checkCancellation()
    return await fetchData()
}

task.cancel()  // 主动取消任务
  • Task 会自动继承当前上下文(如优先级、Actor 等)。
  • 支持任务的 取消(Cancellation)优先级(Priority) 控制。

🤹‍♂️ 4. TaskGroup:并发任务组合 #

✅ 并发处理多个任务: #

func loadMultipleData() async {
    await withTaskGroup(of: String.self) { group in
        for i in 1...3 {
            group.addTask {
                try? await Task.sleep(nanoseconds: UInt64(i) * 1_000_000_000)
                return "任务 \(i) 完成"
            }
        }

        for await result in group {
            print(result)
        }
    }
}

Task {
    await loadMultipleData()
}
  • 自动管理任务的生命周期,避免资源泄漏。
  • 支持异步 for-await-in 遍历结果。

🧵 5. Actor:解决数据竞争的利器 #

✅ 定义 Actor: #

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
}
  • actor 保证 内部状态的线程安全,无需加锁。
  • 数据访问需要使用 await,确保串行化执行。

🎯 6. @MainActor:确保 UI 线程安全 #

@MainActor
class ViewModel: ObservableObject {
    @Published var message = "初始值"

    func updateMessage() {
        message = "更新后的值"
    }
}

Task {
    let vm = ViewModel()
    await vm.updateMessage()  // 自动切换到主线程
}
  • 适用于 SwiftUI 或 UIKit 中的 UI 更新,防止线程冲突。

🌊 7. AsyncSequence:处理异步数据流 #

✅ 异步流示例: #

struct NumberStream: AsyncSequence {
    typealias Element = Int

    func makeAsyncIterator() -> AsyncIterator {
        return AsyncIterator()
    }

    struct AsyncIterator: AsyncIteratorProtocol {
        private var current = 0

        mutating func next() async -> Int? {
            try? await Task.sleep(nanoseconds: 1_000_000_000)
            current += 1
            return current <= 5 ? current : nil
        }
    }
}

Task {
    for await number in NumberStream() {
        print(number)  // 输出 1, 2, 3, 4, 5
    }
}
  • 适合处理 网络流、实时数据更新 等异步场景。

🔄 8. Continuation:兼容旧版回调 #

✅ 将回调封装成异步: #

func legacyAPI(completion: @escaping (String) -> Void) {
    DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
        completion("传统 API 数据")
    }
}

func asyncWrapper() async -> String {
    return await withCheckedContinuation { continuation in
        legacyAPI { result in
            continuation.resume(returning: result)
        }
    }
}

Task {
    let result = await asyncWrapper()
    print(result)  // 输出:传统 API 数据
}
  • Continuation 让传统的回调风格代码可以轻松迁移到新的异步模型中。

🔒 9. Sendable:并发环境下的数据安全 #

✅ 确保类型在多线程间安全传递: #

struct User: Sendable {
    let name: String
    let age: Int
}

let user = User(name: "Alice", age: 30)

Task.detached {
    print(user.name)  // `User` 是线程安全的
}
  • @Sendable 确保数据在跨线程传递时没有副作用,避免竞争条件。

🚦 10. Structured Concurrency(结构化并发) #

  • 核心理念: 父任务创建的子任务会与其共享生命周期,父任务结束时,子任务也会自动取消。
  • 优点:
    • 自动管理内存和资源,减少内存泄漏的风险。
    • 清晰的错误传播链路,方便调试。

✅ 示例: #

func parentTask() async {
    await withTaskGroup(of: Void.self) { group in
        group.addTask { print("子任务 1 执行中") }
        group.addTask { print("子任务 2 执行中") }
    }
    print("父任务完成")
}

Task {
    await parentTask()
}

🚀 总结:Swift 并发的全景图 #

模块作用适用场景
async/await简化异步编程,顺序化异步代码网络请求、数据库操作等异步任务
Task轻量级任务管理,支持取消和优先级并发执行后台任务
TaskGroup并发任务组管理,适合批量任务并发加载数据、批量计算
Actor线程安全的数据保护机制数据共享、避免数据竞争
@MainActor保证主线程执行,适合 UI 相关任务SwiftUI、UIKit 更新
AsyncSequence异步数据流处理,适合流式数据WebSocket、实时数据流
Continuation兼容旧回调风格代码,平滑过渡到新并发模型第三方库、遗留 API 封装
Sendable并发环境下的数据安全标记线程间数据共享
Structured Concurrency父子任务结构化管理,自动处理生命周期高并发任务调度、复杂异步流程控制