在 Swift 中处理任务队列:新手完全指南

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

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

开始课程

Swift 任务队列简介



现代移动和桌面应用程序必须快速且响应灵敏。如果您在主线程中直接执行繁重计算或从网络加载数据,您的应用程序将会卡顿,用户会直接关闭它。解决方案是——任务队列(queues)。



在 Swift(iOS/macOS)中,异步管理建立在三种主要技术之上:Grand Central Dispatch (GCD)、Operation Queue 以及现代语法 async/await。在本文中,我们将从零开始逐一讲解,展示代码示例,并解释何时使用哪种技术。



1. Grand Central Dispatch (GCD) 与 DispatchQueue



GCD 是 Apple 用于管理代码并行执行的低级库。核心元素是 DispatchQueue。队列按添加顺序执行任务(闭包)。



队列类型



  • Main Queue — 主线程串行队列。用于更新 UI。
  • Global Queues — 具有不同优先级(QoS:.userInteractive、.userInitiated、.utility、.background)的并行队列。
  • Custom Queues — 您自己的自定义队列(串行或并行)。


示例:在后台执行任务



import Foundation

// 在后台队列中异步执行DispatchQueue.global(qos: .background).async { // 繁重工作(加载、数据处理) let result = performHeavyTask() // 将结果返回主线程 DispatchQueue.main.async { updateUI(with: result) }}

func performHeavyTask() -> String { Thread.sleep(forTimeInterval: 2) // 模拟工作 return "完成!"}

func updateUI(with text: String) { print("UI 已更新:\\(text)")}


请注意:.async 不会阻塞调用线程。如果需要等待结果,请使用 .sync(但切勿在主线程中调用 .sync——会导致死锁)。



示例:串行队列



let serialQueue = DispatchQueue(label: "com.example.serial")

serialQueue.async { print("任务 1")}serialQueue.async { print("任务 2")}// 输出:任务 1,然后是任务 2


2. Operation Queue — 更灵活的方法



OperationQueue 是 GCD 之上的封装,提供了面向对象的接口。您创建 Operation(或 BlockOperation),配置依赖关系,然后将其添加到队列中。



相较于 GCD 的优势



  • 取消任务(cancel())
  • 任务间的依赖关系
  • 状态监控(isReady、isExecuting、isFinished)
  • 最大并发操作数


示例:基本用法



let operationQueue = OperationQueue()operationQueue.maxConcurrentOperationCount = 2 // 最多同时执行 2 个任务

let operation1 = BlockOperation { print("正在加载数据...") Thread.sleep(forTimeInterval: 1)}

let operation2 = BlockOperation { print("正在处理数据...") Thread.sleep(forTimeInterval: 1)}

// operation2 仅在 operation1 完成后开始operation2.addDependency(operation1)

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


示例:取消操作



let cancelableOp = BlockOperation {    if !cancelableOp.isCancelled {        print("正在执行重要工作")    }}

operationQueue.addOperation(cancelableOp)

// 一段时间后取消DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { cancelableOp.cancel() print("操作已取消")}

博客

书籍推荐