多线程总结
| 需求 | 推荐方案 |
|---|---|
| 简单异步任务 | GCD async |
| 多个任务完成后回调 | dispatch_group |
| 单例 | dispatch_once |
| 延迟执行 | dispatch_after |
| 任务依赖/取消 | NSOperationQueue |
| 限制并发数 | NSOperationQueue 或信号量 |
| 线程安全读写 | dispatch_barrier |
| 线程同步 | dispatch_semaphore 或 NSLock |
记住核心原则:能异步就别同步,能 GCD 就别手动管理线程,UI 永远在主线程。
GCD 与 NSOperationQueue 的核心区别
两者都是 iOS/macOS 中用于处理并发任务的技术,但抽象层级、可控性和适用场景有明显差异。
1. 抽象层级
| 特性 | GCD | NSOperationQueue |
|---|---|---|
| 层级 | C 语言 API,底层 | Objective-C 类,上层抽象 |
| 任务封装 | 直接传 block | NSOperation 对象(可复用) |
| 依赖系统 | 直接基于 libdispatch | 底层由 GCD 实现 |
说明:NSOperationQueue 是对 GCD 的进一步封装,使用更面向对象。
2. 任务控制能力
| 能力 | GCD | NSOperationQueue |
|---|---|---|
| 取消任务 | 一旦提交无法取消(需自行检查标志) | ✅ 可直接调用 cancel()
|
| 挂起/恢复 | 支持队列挂起,但无法单独挂起一个任务 | 支持队列挂起,也可标记单个 operation 依赖 |
| 任务依赖 | ❌ 无原生支持(需用 DispatchGroup 或信号量模拟) | ✅ addDependency: 建立顺序 |
| 优先级 | 队列级(QoS) + 全局队列优先级 | 队列级 + Operation 级优先级 |
| 最大并发数 | 串行/并行两种模式,无自定义并发数 | ✅ 直接设置 maxConcurrentOperationCount
|
| 任务完成状态 | 需手动管理 DispatchGroup | ✅ 支持 KVO 监听 isFinished、isExecuting
|
| 任务暂停/恢复 | 仅能挂起整个队列 | 可以单独控制 operation 启动时机 |
3. 性能与开销
| 维度 | GCD | NSOperationQueue |
|---|---|---|
| 执行效率 | 极高,几乎无额外开销 | 稍低,因为 Operation 对象需要创建、KVO、状态机管理 |
| 内存占用 | 极低 | 每个 Operation 占用更多内存 |
| 提交延迟 | 纳秒级 | 微秒级(可接受) |
结论:GCD 适合高频、轻量任务;NSOperationQueue 适合较复杂、低频的任务编排。
4. 常见使用场景
| 场景 | 推荐 | 原因 |
|---|---|---|
| 网络请求完成后更新 UI | GCD | 简单,轻量 |
| 图片下载并缓存 | NSOperationQueue | 可取消、可调整优先级、可依赖 |
| 大量数学计算(并行 map) | GCD | 性能高,dispatch_apply / concurrentPerform |
| 多个任务顺序执行(串行) | 两者皆可 | GCD 用串行队列,NSOperationQueue 设 maxConcurrent=1 |
| 下载队列支持暂停/继续 | NSOperationQueue | 支持取消单个任务,KVO 便于更新 UI |
| 后台长时间任务(如 CoreData 批量导入) | NSOperationQueue | 可设置依赖,避免 race condition |
5. 重要细节补充
-
取消任务:GCD 没有取消 API,只能通过
dispatch_block_cancel(iOS 8+)配合dispatch_block_create使用,但非常有限;NSOperation 取消需要任务内检查isCancelled。 -
KVO:NSOperation 提供了
isReady、isExecuting、isFinished、isCancelled等 KVO 通知,便于做进度条或状态监控。 - 重用:自定义 NSOperation 子类可封装复杂异步逻辑(如网络请求 + 解析 + 缓存),而 GCD 每次都要写 block,难以复用。
- 优先级反转:两者都有 QoS 传播机制,但 NSOperation 的依赖设计天然避免了部分反转问题。
总结一句话
GCD 是轻量、高效的底层并发工具,适合简单的一次性异步任务;NSOperationQueue 是功能丰富、可控性强的上层框架,适合复杂任务编排、依赖管理、取消与重用。
如果你只需要“丢一个 block 到后台跑完再回主线程”,用 GCD;如果你需要管理多个任务的依赖、取消、优先级、状态监控,选 NSOperationQueue。