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 {
        // 更新UI
        self.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 = false
    private var _isFinished = false
    
    override 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 = true
        main()
    }
    
    override func main() {
        // 异步任务
        asyncTask { [weak self] in
            self?.finish()
        }
    }
    
    func finish() {
        isExecuting = false
        isFinished = 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: DataProducerOperation
    
    init(producer: DataProducerOperation) {
        self.producer = producer
        super.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] in
    guard let self = self else { return }
    // 使用 self
}

operation.completionBlock = { [weak self] in
    guard 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 = error
            cancel()
        }
    }
}

4. 性能优化

swift

复制代码
// 使用适当的 QoS
let queue = OperationQueue()
queue.qualityOfService = .userInitiated

// 或者 GCD
DispatchQueue.global(qos: .userInitiated).async {
    // 重要但不阻塞UI的任务
}

这个完整的知识体系涵盖了 iOS 并发编程的核心概念,从基础的异步执行到复杂

相关推荐
二流小码农3 小时前
鸿蒙开发:this的指向问题
android·ios·harmonyos
马拉萨的春天3 小时前
iOS的事件响应链
macos·ios·cocoa
猪哥帅过吴彦祖7 小时前
Flutter 系列教程:应用导航 - Navigator 1.0 与命名路由
android·flutter·ios
2501_916008898 小时前
iOS 跨平台开发实战指南,从框架选择到开心上架(Appuploader)跨系统免 Mac 发布全流程解析
android·macos·ios·小程序·uni-app·iphone·webview
HarderCoder9 小时前
Swift 并发:我到底该不该用 Actor?——一张决策图帮你拍板
swift
鹏多多9 小时前
flutter图片选择库multi_image_picker_plus和image_picker的对比和使用解析
android·flutter·ios
HarderCoder9 小时前
深入理解 DispatchQueue.sync 的死锁陷阱:原理、案例与最佳实践
swift
东坡肘子9 小时前
Skip Fuse现在对独立开发者免费! -- 肘子的 Swift 周报 #0110
android·swiftui·swift