NSOperation与大中央调度

我正在学习iOS的并发编程。 到目前为止,我已经读过NSOperation / NSOperationQueueGCD使用NSOperationQueue的原因是什么,反之亦然?

听起来像GCDNSOperationQueue抽象的从用户显式创buildNSThreads 。 然而这两种方法之间的关系对我来说是不清楚的,所以任何反馈都要赞赏!

GCD是一个低级的基于C的API,可以非常简单地使用基于任务的并发模型。 NSOperationNSOperationQueue是类似的东西的Objective-C类。 NSOperation介绍了NSOperation ,但是从10.6和iOS 4开始, NSOperationQueue和朋友们都是使用GCD在内部实现的。

一般来说,您应该使用适合您需求的最高抽象级别。 这意味着你通常应该使用NSOperationQueue而不是GCD ,除非你需要做一些NSOperationQueue不支持的东西。

请注意, NSOperationQueue不是GCD的“简化”版本; 事实上, NSOperationQueue可以很简单的完成很多工作。 (例如:一次只能运行N个操作的带宽受限的队列;build立操作之间的依赖关系,两者都非常简单,在GCD非常困难)。苹果公司利用GCD创build了一个非常好的对象友好的API与NSOperation 。 除非你有理由不要,否则请利用他们的工作。

警告 :另一方面,如果你真的只需要发送一个块,并且不需要NSOperationQueue提供的任何附加function, NSOperationQueue使用GCD就没有任何问题。 只要确定它是这个工作的正确工具。

根据我对一个相关问题的回答 ,我会不同意BJ,并build议你首先看GCD而不是NSOperation / NSOperationQueue,除非后者提供了GCD不需要的东西。

在GCD之前,我在我的应用程序中使用了很多NSOperations / NSOperationQue来pipe理并发。 然而,自从我开始定期使用GCD之后,我几乎完全用块和调度队列取代了NSOperations和NSOperationQueue。 这来自于我在实践中如何使用这两种技术,以及从我对它们进行的分析。

首先,当使用NSOperations和NSOperationQueues时,会有一些不必要的开销。 这些是Cocoa对象,他们需要分配和释放。 在我写的iOS应用程序中,它以60 FPS渲染一个3D场景,我使用NSOperations来封装每个渲染帧。 当我描述这个时候,这些NSOperations的创build和拆卸在正在运行的应用程序中占据了CPU周期的很大一部分,并且正在放慢速度。 我用简单的块和GCD串行队列取代了这些,并且开销消失,导致显着更好的渲染性能。 这不是我唯一注意到使用NSOperations的地方,我已经在Mac和iOS上看到了这一点。

其次,在使用NSOperations时,很难匹配基于块的调度代码。 将几行代码包装在一个块中,并将其派发到串行队列或并发队列中是非常方便的,创build一个自定义NSOperation或NSInvocationOperation来执行此操作需要更多的支持代码。 我知道你可以使用NSBlockOperation,但是你也可以把它们发给GCD。 将这些代码与你的应用程序中的相关处理嵌套在一起,在我看来导致更好的代码组织,而不是单独的方法或封装这些任务的自定义NSOperations。

NSOperations和NSOperationQueues仍然有非常好的用途。 GCD没有真正的依赖概念,NSOperationQueues可以设置相当复杂的依赖关系图。 我在less数情况下使用NSOperationQueues。

总的来说,虽然我通常主张使用最高级别的抽象来完成任务,但这是我为GCD的低级API所争辩的一个案例。 在我曾经讨论过的iOS和Mac开发者中,绝大多数人select使用GCD而不是NSOperations,除非他们的操作系统版本不支持(iOS 4.0和Snow Leopard之前的版本)。

GCD的确低于NSOperationQueue,它的主要优点是它的实现非常轻量级,专注于无锁algorithm和性能。

NSOperationQueue确实提供了GCD中没有的function,但是它们的花费并不是很小,NSOperationQueue的实现是复杂的,重量级的,涉及到大量的locking,并且只以非常小的方式在内部使用GCD。

如果您需要使用NSOperationQueue提供的function,但是如果GCD足够满足您的需求,我build议您直接使用它来获得更好的性能,显着降低CPU和功耗成本,并提高灵活性。

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

另外与NSOperation,KVO可能是可能的。

这是来自Eschaton的一篇值得一读的文章。

GCD是一个低级的基于C的API。
NSOperationNSOperationQueue是Objective-C类。
NSOperationQueueGCD客观C封装。 如果你正在使用NSOperation,那么你隐式使用Grand Central Dispatch。

GCD优于NSOperation:
一世。 履行
对于GCD实施是非常轻量级的
NSOperationQueue是复杂和重量级的

GCD的优势:

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

II。 依赖
你可以在两个NSOperations之间build立一个依赖关系
操作将不会开始,直到所有的依赖关系返回true为止。

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

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

何时去GCDNSOperation
当你想要对队列进行更多的控制时(使用上面提到的),使用NSOperation ,对于你想要较less开销的简单情况(你只需要做一些“进入后台”的工作,只需很less的额外工作)就可以使用GCD

参考:
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/

NSQueueOperations和GCD都允许通过释放UI应用程序主线程在独立的线程后台执行繁重的计算任务。

那么,基于以前的post,我们看到NSOperations已经添加依赖,以便您可以顺序排列您的操作一个接一个。

但是我也读了关于可以创build的GCD串行队列,使用dispatch_queue_create在队列中运行你的操作。 这将允许以顺序方式一个接一个地运行一组操作。

NSQueueOperation优于GCD:

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

  2. 如果它在队列中,那么取消操作很容易,如果它正在运行,它可以被停止。

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

  4. 您可以暂停他们在队列中的操作

  5. 你可以在队列中find有多less挂起的操作。

GCD非常易于使用 – 如果您想在后台执行某些操作,您只需编写代码并将其分派到后台队列中即可。 与NSOperation做同样的事情是很多额外的工作。

NSOperation的优点是(a)你有一个真正的对象,你可以发送消息,(b)你可以取消一个NSOperation。 这不是微不足道的。 你需要子类NSOperation,你必须正确编写你的代码,以便取消和正确完成一个任务都正常工作。 因此,对于使用GCD的简单事情,对于更复杂的事情,您可以创buildNSOperation的子类。 (有NSInvocationOperation和NSBlockOperation的子类,但是他们做的所有事情都可以用GCD轻松完成,所以没有什么理由使用它们)。

那么NSOperations只是一个build立在Grand Central Dispatch之上的API。 所以当你使用NSOperations的时候,你真的还在使用Grand Central Dispatch。 这只是NSOperations给你一些你可能喜欢的奇特function。 你可以做一些依赖于其他操作的操作,在你放弃物品之后重新排列队列,以及其他类似的东西。 其实ImageGrabber已经在使用NSOperations和操作队列了! ASIHTTPRequest使用它们,你可以根据需要configuration它用于不同行为的操作队列。 那么你应该使用哪个? 哪一个对你的应用程序有意义。 对于这个应用程序来说非常简单,所以我们直接使用Grand Central Dispatch,不需要NSOperation的特殊function。 但是,如果你需要他们为您的应用程序,请随时使用它!