Swift 中的任务队列:从 GCD 到 Swift Concurrency
在 iOS 和 macOS 开发中,管理代码的并行执行是一项关键任务。任务队列 (queues) 可以有效地在线程之间分配负载,而不会阻塞用户界面。在本指南中,我们将介绍三种主要方法:经典的 Grand Central Dispatch (GCD)、抽象层 OperationQueue 以及现代机制 Swift Concurrency (async/await)。
1. Grand Central Dispatch (GCD) — 并行基础
GCD 是一个集成在 Swift 中的底层 C 语言库。它管理线程池,并提供两种类型的队列:
- 串行队列 (Serial) — 任务按添加顺序一个接一个地执行。
- 并发队列 (Concurrent) — 任务同时启动,完成顺序不保证。
创建和使用队列的示例:
import Foundation
// 创建一个串行队列let serialQueue = DispatchQueue(label: "com.example.serial")
serialQueue.async { print("任务 1 开始") sleep(1) print("任务 1 完成")}
serialQueue.async { print("任务 2 开始") sleep(1) print("任务 2 完成")}
// 并发队列let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)
concurrentQueue.async { print("并发任务 A")}
concurrentQueue.async { print("并发任务 B")}GCD 的关键功能:
DispatchQueue.main— 主队列(UI 线程)。DispatchQueue.global(qos: .userInitiated)— 具有优先级 (QoS) 的全局队列。dispatchGroup— 同步多个任务。dispatchSemaphore— 控制对资源的访问。
2. OperationQueue — 面向对象的抽象层
OperationQueue 构建在 GCD 之上,但提供了更高级别的 API。主要优点:
- 管理操作之间的依赖关系。
- 取消任务 (cancel)。
- 状态监控 (isFinished, isExecuting)。
- 最大并发操作数。
使用 BlockOperation 的示例:
import Foundation
let operationQueue = OperationQueue()operationQueue.maxConcurrentOperationCount = 2
let operation1 = BlockOperation { print("操作 1:加载数据") sleep(2) print("操作 1 完成")}
let operation2 = BlockOperation { print("操作 2:处理") sleep(1) print("操作 2 完成")}
// 设置依赖关系:操作 2 仅在操作 1 完成后开始operation2.addDependency(operation1)
operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)
// 取消操作operation1.cancel()何时使用 OperationQueue:
- 具有依赖关系的复杂任务链。
- 需要精细控制(暂停、取消)。
- 使用 KVO (Key-Value Observing) 进行监控。
3. Swift Concurrency — 现代方法 (iOS 13+, macOS 10.15+)
从 Swift 5.5 开始,Apple 通过 async/await、Task 和 TaskGroup 引入了对异步编程的内置支持。这是一种更安全、更易读的并行处理方法。
基本示例:
import Foundation
func fetchUserData() async -> String { // 模拟网络请求 try? await Task.sleep(nanoseconds: 2 * 1_000_000_000) return "用户数据已加载"}
func processData()