Swift-GCD和NSOperation
iOS的GCD和NSOperation的swift版本,全部知识体系
以下是 iOS 中 GCD 和 Operation (NSOperation 的 Swift 版本) 的完整知识体系:
GCD (Grand Central Dispatch) - Swift 版本
1. 基础概念
队列类型
swift
// 主队列 - 串行 let mainQueue = DispatchQueue.main// 全局队列 - 并发 let globalQueue = DispatchQueue.global() let globalBackground = DispatchQueue.global(qos: .background)// 自定义队列 let serialQueue = DispatchQueue(label: "com.example.serial") let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)
QoS 优先级
swift
.userInteractive // 用户交互,最高优先级 .userInitiated // 用户发起 .default // 默认 .utility // 实用任务 .background // 后台任务 .unspecified // 未指定
2. 基本使用
异步执行
swift
// 后台执行,主线程更新UI
DispatchQueue.global(qos: .background).async {// 执行耗时任务let result = heavyCalculation()DispatchQueue.main.async {// 更新UIself.updateUI(with: result)}
}延迟执行
swift
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {print("2秒后执行")
}// 精确延迟
let deadline = DispatchTime.now() + .milliseconds(500)
DispatchQueue.main.asyncAfter(deadline: deadline) {print("500毫秒后执行")
}3. 高级特性
DispatchGroup - 任务组
swift
let group = DispatchGroup()group.enter()
networkRequest1 { result in// 处理结果group.leave()
}group.enter()
networkRequest2 { result in// 处理结果group.leave()
}// 所有任务完成通知
group.notify(queue: .main) {print("所有任务完成")
}// 或者等待完成
group.wait(timeout: .now() + 10)DispatchWorkItem - 工作任务
swift
let workItem = DispatchWorkItem {print("执行工作任务")
}// 可以取消
workItem.cancel()// 执行
DispatchQueue.global().async(execute: workItem)// 完成任务通知
workItem.notify(queue: .main) {print("工作任务完成")
}DispatchSemaphore - 信号量
swift
let semaphore = DispatchSemaphore(value: 3) // 同时最多3个任务for i in 0..<10 {DispatchQueue.global().async {semaphore.wait() // 获取信号量// 执行受限任务performTask(i)semaphore.signal() // 释放信号量}
}DispatchBarrier - 屏障
swift
let concurrentQueue = DispatchQueue(label: "com.example.barrier", attributes: .concurrent)// 并发读取
for i in 0..<5 {concurrentQueue.async {print("读取操作 \(i)")}
}// 屏障写入 - 等待所有读取完成,执行写入,期间阻塞其他操作
concurrentQueue.async(flags: .barrier) {print("写入操作 - 屏障")
}// 屏障后的读取
for i in 5..<10 {concurrentQueue.async {print("读取操作 \(i)")}
}4. 源 (DispatchSource)
定时器源
swift
let timer = DispatchSource.makeTimerSource(queue: .global())
timer.schedule(deadline: .now(), repeating: 1.0)
timer.setEventHandler {print("定时器触发")
}
timer.resume()文件监视
swift
let fileURL = URL(fileURLWithPath: "/path/to/file")
let fileDescriptor = open(fileURL.path, O_EVTONLY)let source = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor,eventMask: .write,queue: .global()
)source.setEventHandler {print("文件被修改")
}
source.resume()Operation (NSOperation 的 Swift 版本)
1. 基础概念
基本使用
swift
// BlockOperation - 块操作
let operation = BlockOperation {print("执行操作")
}// 添加多个块
operation.addExecutionBlock {print("另一个执行块")
}let queue = OperationQueue()
queue.addOperation(operation)2. 自定义 Operation
同步操作
swift
class SimpleOperation: Operation {override func main() {guard !isCancelled else { return }// 执行任务print("执行简单操作")}
}异步操作
swift
class AsyncOperation: Operation {private let lockQueue = DispatchQueue(label: "com.example.asyncop", attributes: .concurrent)private var _isExecuting = falseprivate var _isFinished = falseoverride var isAsynchronous: Bool { return true }override var isExecuting: Bool {get { return lockQueue.sync { _isExecuting } }set {willChangeValue(forKey: "isExecuting")lockQueue.sync(flags: [.barrier]) { _isExecuting = newValue }didChangeValue(forKey: "isExecuting")}}override var isFinished: Bool {get { return lockQueue.sync { _isFinished } }set {willChangeValue(forKey: "isFinished")lockQueue.sync(flags: [.barrier]) { _isFinished = newValue }didChangeValue(forKey: "isFinished")}}override func start() {guard !isCancelled else {finish()return}isExecuting = truemain()}override func main() {// 异步任务asyncTask { [weak self] inself?.finish()}}func finish() {isExecuting = falseisFinished = true}
}3. OperationQueue 管理
队列配置
swift
let queue = OperationQueue()// 配置 queue.name = "com.example.operationqueue" queue.maxConcurrentOperationCount = 3 // 并发数 queue.qualityOfService = .userInitiated// 暂停/恢复 queue.isSuspended = true queue.isSuspended = false// 取消所有操作 queue.cancelAllOperations()
添加操作
swift
let operation1 = BlockOperation { print("操作1") }
let operation2 = BlockOperation { print("操作2") }
let operation3 = BlockOperation { print("操作3") }queue.addOperation(operation1)
queue.addOperations([operation2, operation3], waitUntilFinished: false)// 添加完成块
operation1.completionBlock = {print("操作1完成")
}4. 依赖关系
swift
let downloadOp = BlockOperation { print("下载") }
let parseOp = BlockOperation { print("解析") }
let saveOp = BlockOperation { print("保存") }// 设置依赖
parseOp.addDependency(downloadOp)
saveOp.addDependency(parseOp)queue.addOperations([downloadOp, parseOp, saveOp], waitUntilFinished: false)5. 高级特性
KVO 观察
swift
class OperationObserver: NSObject {func observe(operation: Operation) {operation.addObserver(self, forKeyPath: "isFinished", options: .new, context: nil)operation.addObserver(self, forKeyPath: "isCancelled", options: .new, context: nil)}override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {if let op = object as? Operation {print("操作状态变化: \(keyPath!) = \(change?[.newKey] ?? "")")}}
}Operation 间的数据传递
swift
class DataProducerOperation: Operation {var outputData: String?override func main() {outputData = "生产的数据"}
}class DataConsumerOperation: Operation {let producer: DataProducerOperationinit(producer: DataProducerOperation) {self.producer = producersuper.init()addDependency(producer)}override func main() {guard let data = producer.outputData else { return }print("消费数据: \(data)")}
}对比和选择指南
GCD vs Operation
| 特性 | GCD | Operation |
|---|---|---|
| 抽象级别 | 较低,C-based | 较高,面向对象 |
| 取消操作 | 有限 (DispatchWorkItem) | 完善支持 |
| 依赖管理 | 手动 (DispatchGroup) | 内置支持 |
| 状态观察 | 无 | KVO 支持 |
| 暂停恢复 | 队列级别 | 操作级别 |
| 适用场景 | 简单并发任务 | 复杂任务依赖 |
使用场景
使用 GCD 当:
swift
// 简单的后台任务
DispatchQueue.global().async {let data = loadData()DispatchQueue.main.async {self.updateUI(with: data)}
}// 延迟执行
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {self.showMessage()
}// 资源限制
let semaphore = DispatchSemaphore(value: 2)使用 Operation 当:
swift
// 复杂任务依赖
let downloadOp = DownloadOperation()
let processOp = ProcessOperation()
let uploadOp = UploadOperation()processOp.addDependency(downloadOp)
uploadOp.addDependency(processOp)queue.addOperations([downloadOp, processOp, uploadOp])// 需要取消的任务
downloadOp.completionBlock = {if downloadOp.isCancelled {print("下载被取消")}
}// 批量操作管理
queue.addBarrierBlock {print("所有操作完成")
}最佳实践
1. 避免线程爆炸
swift
// GCD - 使用信号量限制 let semaphore = DispatchSemaphore(value: 4)// Operation - 设置并发数 queue.maxConcurrentOperationCount = 4
2. 内存管理
swift
// 使用 [weak self] 避免循环引用
DispatchQueue.global().async { [weak self] inguard let self = self else { return }// 使用 self
}operation.completionBlock = { [weak self] inguard let self = self else { return }// 使用 self
}3. 错误处理
swift
class SafeOperation: Operation {private var _error: Error?var error: Error? {return _error}override func main() {do {try performTask()} catch {_error = errorcancel()}}
}4. 性能优化
swift
// 使用适当的 QoS
let queue = OperationQueue()
queue.qualityOfService = .userInitiated// 或者 GCD
DispatchQueue.global(qos: .userInitiated).async {// 重要但不阻塞UI的任务
}这个完整的知识体系涵盖了 iOS 并发编程的核心概念,从基础的异步执行到复杂
