Swift中的并发与多线程:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Swift 中的并发与多线程简介

现代 iOS 和 macOS 应用程序越来越需要同时执行多个任务。无论是从网络加载数据、处理图像还是进行复杂的数学计算,都离不开对线程的有效管理。在 Swift 中,并发与多线程的实现达到了最高水平,为开发者提供了强大且安全的工具。

在本文中,我们将介绍三种主要方法:Grand Central Dispatch (GCD)、OperationQueue 以及 Swift 5.5 中引入的现代关键字 async/await。您将学习如何正确选择它们,并避免典型错误,例如竞态条件 (race condition) 和死锁 (deadlock)。



Grand Central Dispatch (GCD) — Swift 中的经典多线程

Grand Central Dispatch (GCD) 是 Apple 的一个底层库,用于管理线程池。开发者无需手动创建和销毁线程——GCD 会自动完成这些工作,将任务分配到可用的 CPU 核心上。



GCD 的主要队列

GCD 有两种类型的队列:串行队列 (serial) 和并发队列 (concurrent)。串行队列中的任务一个接一个地执行,而并发队列中的任务可以同时启动。

// 创建串行队列let serialQueue = DispatchQueue(label: "com.example.serial")serialQueue.async {    print("任务 1")}serialQueue.async {    print("任务 2")}

// 创建并发队列let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)concurrentQueue.async { print("并发任务 A")}concurrentQueue.async { print("并发任务 B")}


全局队列与 QoS

GCD 提供了现成的具有不同优先级 (Quality of Service) 的全局队列。当不需要创建自己的队列时,可以使用它们:

  • .userInteractive — 用于 UI 更新(最高优先级)
  • .userInitiated — 用于用户发起的任务
  • .utility — 用于长时间的后台操作
  • .background — 用于对时间不敏感的任务
DispatchQueue.global(qos: .userInitiated).async {    // 繁重的工作    let result = performComplexCalculation()    DispatchQueue.main.async {        // 返回主线程更新 UI        self.updateUI(with: result)    }}

重要提示: 始终只在主线程 (DispatchQueue.main) 上更新 UI。忽略此规则会导致应用程序出现不可预测的崩溃。



OperationQueue — 任务依赖管理

如果说 GCD 是“瑞士军刀”,那么 OperationQueue 就是一个功能完备的调度器,支持取消、优先级设置以及创建操作之间的依赖关系。每个操作都是 Operation 类(或其子类 BlockOperation)的一个实例。



创建和执行操作

let operationQueue = OperationQueue()operationQueue.maxConcurrentOperationCount = 2 // 限制并发操作数量

let operation1 = BlockOperation { print("操作 1")}let operation2 = BlockOperation { print("操作 2")}

// 添加依赖:operation2 只有在 operation1 完成后才会开始operation2.addDependency(operation1)

operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)


取消与优先级

与 GCD 不同,OperationQueue 允许取消特定操作或整个队列:

// 取消一个操作operation1.cancel()

// 取消整个队列operationQueue.cancelAllOperations()

// 设置优先级operation1.

博客

书籍推荐