首页 文章

NSOperation vs Grand Central Dispatch

提问于
浏览
443

我'm learning about concurrent programming for iOS. So far I'已经阅读了NSOperation/NSOperationQueueGCD . What are the reasons for using NSOperationQueue over GCD and vice versa?

听起来像 GCDNSOperationQueue 抽象了用户明确创建 NSThreads . 然而这两种方法之间的关系对我来说并不清楚,所以任何反馈都要赞赏!

8 回答

  • 358

    GCD 是一个基于C的低级API,可以非常简单地使用基于任务的并发模型 . NSOperationNSOperationQueue 是做类似事情的Objective-C类 . NSOperation 首先被介绍,但是从10.6和iOS 4开始, NSOperationQueue 和朋友在内部使用 GCD 实现 .

    通常,您应该使用最适合您需求的抽象级别 . 这意味着您通常应该使用 NSOperationQueue 而不是 GCD ,除非您需要执行 NSOperationQueue 不支持的操作 .

    请注意 NSOperationQueue 不是GCD的"dumbed-down"版本;事实上,有许多事情你可以非常简单地使用 NSOperationQueue 来完成纯粹 GCD 的大量工作 . (示例:带宽受限的队列,一次只运行N个操作;在操作之间 Build 依赖关系 . 两者都很简单 NSOperation ,非常难以使用 GCD . )Apple完成了利用GCD创建非常好的对象友好API的艰苦工作与 NSOperation . 除非你有理由不去利用他们的工作 .

    Caveat :另一方面,如果你真的只需要发送一个块,并且不需要 NSOperationQueue 提供的任何附加功能,那么's nothing wrong with using GCD. Just be sure it'就是这个工作的正确工具 .

  • 495

    符合my answer to a related question,我'm going to disagree with BJ and suggest you first look at GCD over NSOperation / NSOperationQueue, unless the latter provides something you need that GCD doesn' t .

    在GCD之前,我在我的应用程序中使用了很多NSOperations / NSOperationQueues来管理并发 . 但是,由于我开始定期使用GCD,我几乎完全用块和调度队列替换了NSOperations和NSOperationQueues . 这来自我在实践中如何使用这两种技术,以及我对它们进行的分析 .

    首先,使用NSOperations和NSOperationQueues时会产生大量的开销 . 这些是Cocoa对象,需要分配和释放它们 . 在我编写的iOS应用程序中,它以60 FPS呈现3D场景,我使用NSOperations来封装每个渲染帧 . 当我对此进行分析时,这些NSOperations的创建和拆除占了正在运行的应用程序中CPU周期的很大一部分,并且正在减慢速度 . 我用简单的块和GCD串行队列替换了这些,并且开销消失了,导致明显更好的渲染性能 . 这不是我注意到使用NSOperations的唯一开销,我在Mac和iOS上都看到了这一点 .

    其次,使用NSOperations时很难匹配基于块的调度代码 . 将一行代码包装在一个块中并将其分派以在串行或并发队列上执行是非常方便的,其中创建自定义NSOperation或NSInvocationOperation来执行此操作需要更多支持代码 . 我知道你可以使用NSBlockOperation,但你也可以向GCD发送一些东西 . 将这些代码包含在与应用程序中的相关处理内联的块中,导致我认为比使用单独的方法或封装这些任务的自定义NSOperations更好地编写代码组织 .

    NSOperations和NSOperationQueues仍然有很好的用途 . GCD没有真正的依赖概念,其中NSOperationQueues可以设置相当复杂的依赖图 . 在少数情况下我使用NSOperationQueues .

    总的来说,虽然我通常主张使用最高级别的抽象来完成任务,但这是我争论GCD的低级API的一个案例 . 在我与之谈过的iOS和Mac开发人员中,绝大多数人选择使用GCD而不是NSOperations,除非他们针对OS版本而不支持它(iOS 4.0和Snow Leopard之前) .

  • 3

    GCD 是一个基于C的低级API .
    NSOperationNSOperationQueue 是Objective-C类 .
    NSOperationQueueGCD 上的客观C包装器 . 如果您使用的是NSOperation,那么您将隐式使用Grand Central Dispatch .

    GCD advantage over NSOperation:
    一世 . 履行
    对于 GCD 实施非常轻量级
    NSOperationQueue 复杂而且重量很重

    NSOperation advantages over GCD:

    一世 . 控制操作
    你可以暂停,取消,恢复 NSOperation

    II . 依赖
    你可以设置两个之间的依赖关系 NSOperations
    在完成所有依赖关系返回true之前,操作不会启动 .

    III . 运作状况
    可以监视操作或操作队列的状态 . 准备好,执行或完成

    IV . 最大操作次数
    您可以指定可以同时运行的最大排队操作数

    When to Go for GCD or NSOperation
    当你想要更多地控制队列时(上面提到的所有内容)使用 NSOperation 并且对于你想要更少开销的简单情况(你只想做一些工作"into the background",只需要很少的额外工作)使用 GCD

    ref:
    https://cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/ http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperationqueue.html http://nshipster.com/nsoperation/

  • 33

    GCD确实比NSOperationQueue低,它的主要优点是它的实现非常轻巧,并且专注于无锁算法和性能 .

    NSOperationQueue确实提供了GCD中没有的设施,但它们的成本非常高,NSOperationQueue的实现既复杂又重,涉及大量锁定,并且只在极小的时候内部使用GCD .

    如果您需要NSOperationQueue提供的设施,请务必使用它,但如果GCD足以满足您的需求,我建议您直接使用它以获得更好的性能,显着降低CPU和电源成本并提高灵活性 .

  • 5

    NSOperation优于GCD的另一个原因是NSOperation的取消机制 . 例如,一个像500px的应用程序可以显示数十张照片,使用NSOperation我们可以在滚动表视图或集合视图时取消不可见图像单元格的请求,这样可以大大提高App性能并减少内存占用 . GCD不能轻易支持这一点 .

    通过NSOperation,KVO也是可能的 .

    Here是Eschaton的一篇文章,值得一读 .

  • 23

    NSQueueOperations和GCD都允许通过释放UI Application Main Tread在后台执行繁重的计算任务 .

    好吧,基于上一篇文章,我们看到NSOperations有addDependency,因此您可以按顺序依次对操作进行排队 .

    但我还读到了您可以使用dispatch_queue_create在队列中运行您的操作的GCD串行队列 . 这将允许以顺序方式一个接一个地运行一组操作 .

    NSQueueOperation相对于GCD的优势:

    • 它允许添加依赖关系并允许您删除依赖关系,因此对于一个事务,您可以使用依赖关系运行顺序,并且同时运行其他事务,而GCD不允许以这种方式运行 .

    • 如果操作在队列中很容易取消,如果它正在运行则可以停止 .

    • 您可以定义最大并发操作数 .

    • 您可以暂停它们在队列中的操作

    • 您可以在队列中找到有多少挂起操作 .

  • 82

    GCD非常易于使用 - 如果你想在后台做一些事情,你需要做的就是编写代码并将它发送到后台队列 . 使用NSOperation做同样的事情还有很多额外的工作 .

    NSOperation的优势在于:(a)您有一个可以发送消息的真实对象,以及(b)您可以取消NSOperation . 这不是微不足道的 . 您需要子类化NSOperation,您必须正确编写代码,以便取消和正确完成任务都能正常工作 . 因此,对于简单的事物,您使用GCD,对于更复杂的事物,您可以创建NSOperation的子类 . (有NSInvocationOperation和NSBlockOperation的子类,但是他们所做的一切都很容易用GCD完成,因此没有充分的理由使用它们) .

  • 33

    那么,NSOperations只是 Build 在Grand Central Dispatch之上的API . 因此,当您使用NSOperations时,您仍然使用Grand Central Dispatch . 只是NSOperations为您提供了一些您可能喜欢的精彩功能 . 您可以使一些操作依赖于其他操作,在汇总项目后重新排序队列,以及其他类似的操作 . 事实上,ImageGrabber已经在使用NSOperations和操作队列了! ASIHTTPRequest在底层使用它们,如果您愿意,可以配置它用于不同行为的操作队列 . 那你应该用哪个?哪个对你的应用有意义 . 对于这个应用程序它非常简单,所以我们直接使用Grand Central Dispatch,不需要NSOperation的花哨功能 . 但如果您的应用需要它们,请感受一下免费使用它!

相关问题