8-1.【OC】【NSOperation】NSOperation 与 GCD 的异同?

3 阅读3分钟

在 iOS 多线程开发中,NSOperationGCD(Grand Central Dispatch)的关系可以类比为:NSOperation 是对 GCD 的高级面向对象封装。

虽然底层都利用了线程池,但它们在设计哲学和使用场景上有显著差异。


1. 核心差异对比

特性GCD (C 语言级别)NSOperation (Obj-C/Swift 级别)
抽象层次底层 API,基于闭包(Block)高层抽象,基于对象(Object)
任务依赖实现较复杂(需使用 Group/Barrier)天生支持(通过 addDependency:
取消/暂停较难(只能取消尚未执行的任务)非常简单(支持 cancel, pause, resume
执行顺序FIFO(队列先进先出)支持优先级queuePriority
状态追踪无法直接得知任务进度支持监听 isFinished, isExecuting
性能开销极小,执行速度最快略高(因为有对象创建和状态管理的开销)

2. NSOperation 的独特优势

A. 强大的依赖关系 (Dependencies)

你可以轻松指定任务 A 必须在任务 B 完成后执行,即使它们在不同的队列中。这在处理复杂的网络请求序列或大文件下载、解压、存储流时非常有用。

Swift

downloadOp.addDependency(unzipOp) // 只有下载完才会解压

B. 灵活的状态监控

NSOperation 提供了一系列 KVO 属性,让你可以实时监控任务的生命周期。

  • isReady: 是否准备好执行。
  • isExecuting: 是否正在运行。
  • isFinished: 是否已完成(包括成功或被取消)。
  • isCancelled: 是否已取消。

C. 最大并发数控制

通过 maxConcurrentOperationCount,你可以精确控制同时运行的线程数量。这在保护系统资源(如限制同时进行的图片解码数量)时非常有效。


3. GCD 的独特优势

A. 极致的性能

GCD 是基于 C 语言的,直接与系统内核通信。在处理极其频繁、微小的后台任务时,GCD 的分发延迟更低。

B. 丰富的同步原语

  • Dispatch Group:监控一组任务是否全部完成。
  • Dispatch Semaphore:控制资源访问频率(信号量)。
  • Dispatch Barrier:解决“读者-写者”问题,保证线程安全。
  • Once (仅限 OC) :确保代码只执行一次(单例模式常用)。

4. 什么时候用哪个?

推荐使用 NSOperation 的场景:

  • 任务间有依赖关系:例如“先登录 -> 再拉取配置 -> 再下载资源”。
  • 需要随时取消任务:例如在列表快速滚动时,取消已经滑出屏幕的图片下载任务。
  • 需要重用代码:你可以通过继承 Operation 类来封装复杂的业务逻辑。

推荐使用 GCD 的场景:

  • 简单的后台处理:仅仅是想把一段耗时代码丢到后台执行。
  • 线程同步/资源保护:需要加锁或使用信号量来保护全局变量。
  • 一次性逻辑:只需要执行一次的任务。

总结:封装的力量

GCD 是“执行单元”,侧重于“分发”;NSOperation 是“任务对象”,侧重于“控制”。

在现代项目中,如果业务逻辑比较重,建议优先考虑 NSOperation,因为它能提供更好的可维护性和结构化代码。如果是轻量级的并发控制,GCD 依然是效率之王。