我为什么要selectGCD而不是NSOperation,并为高级应用程序块?

苹果的Grand Central Dispatch参考说:

“…如果您的应用程序需要在系统的Unix级别上运行 – 例如,如果需要操作文件描述符,Mach端口,信号或定时器,GCD不限于系统级应用程序,而是在您之前将它用于更高级别的应用程序,您应该考虑Cocoa中提供的类似function(通过NSOperation和块对象)是否更容易使用或更适合您的需求。“

http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

我实际上不能想到高级应用的情况,在这种情况下,GCD的使用是强制性的,NSOperation可以/不应该使用。

有什么想法吗?

在这里提出的观点与Chris Hanson在他的文章“ 何时使用NSOperation vs. GCD ”中提到的是一样的 :

直接的答案是所有应用程序开发的一般指导原则:

始终使用可用的最高级别抽象,并在测量显示需要时抽取较低级别的抽象。

在这种情况下,这意味着在编写Cocoa应用程序时,通常应该使用NSOperation,而不是直接使用GCD。 不是因为效率的差异,而是因为NSOperation在GCD的机制之上提供了更高层次的抽象。

总的来说,我同意这一点。 NSOperation和NSOperationQueue为依赖和GCD块和队列没有的一两个其他事物提供支持,并且抽象出并发操作如何实现的底层细节。 如果你需要这个function,NSOperation是一个非常好的方法。

但是,在使用两者之后,我发现自己用GCD块和队列replace了所有基于NSOperation的代码。 我这样做的原因有两个:在使用NSOperation进行频繁操作时会产生很大的开销,而且我相信在使用GCD块时我的代码更干净,更具描述性。

第一个原因来自我的应用程序分析,我发现NSOperation对象分配和释放过程在处理小而频繁的操作时花费了大量的CPU资源,比如在屏幕上渲染OpenGL ES框架。 GCD块完全消除了开销,导致显着的性能改进。

第二个原因更主观,但我相信我的代码比NSOperations更清晰。 块所允许的范围的快速捕获和它们的内联特性使得代码更less,因为您不需要创build自定义的NSOperation子类或捆绑参数来传递到操作中,在我看来,更多的描述性代码,因为您可以将代码放置在队列中的位置。

再次,它是一个偏好的问题,但我发现自己更多地使用GCD,即使在其他更抽象的cocoa应用程序。

  • 首选GCD,其任务并不复杂,需要最佳的CPU性能
  • 首选NSOperationQueue,其任务非常复杂,需要取消或挂起块和依赖关系pipe理

GCD是一种轻量级的方式来表示要同时执行的工作单元。 你不安排这些工作单位; 系统会为您安排时间安排。 在块之间添加依赖可能是一个头痛的问题。 取消或暂停一个块为开发者创造额外的工作!

NSOperation和NSOperationQueue相比GCD增加了一些额外的开销,但是您可以在各种操作之间添加依赖关系。 您可以重新使用,取消或暂停操作。 NSOperation与Key-Value Observation(KVO)兼容; 例如,您可以通过侦听NSNotificationCenter来启动NSOperation。

有关详细的解释,请参考下面的问题: NSOperation和Grand Central Dispatch

那么,NSOperation有没有等同于dispatch_source_t,dispatch_io,dispatch_data_t,dispatch_semaphore_t等…这也有点更高的开销。

另一方面,libdispatch没有与操作依赖关系,操作优先级(队列优先级有所不同)或KVO操作的等价物。

NSOperationQueue可以做两件事:GCD不做:次要的依赖关系(向队列中添加一个操作,但是告诉它只在某些其他操作完成时才执行),最重要的是NSOperation会给你一个可以在任务执行时接收消息的对象,而不像GCD那样,除非是非常有限的方式,GCD不能接收消息。 你要么需要这两个function,要么你不需要。 如果你不这样做,使用GCD只是一个非常容易使用。

这就是为什么NSOperation的有用例子总是相当复杂。 如果他们很容易,你可以使用GCD。 你通常创build一个NSOperation的子类,这将是一些大量的工作,或使用别人创build的一个。

其实我只是一直在读这篇文章,而且我相信这将是知道的惊喜,不同的意见。

我不能想到一个情况,你必须使用GCD而不是NSOperation,但这并不意味着这种情况不存在。 然而,我同意最佳实践编码方面的普遍观点:

如果你有一些适合工作的工具(在这种情况下,你有NSOperation与GCD块),使用抽象级别最高的类(即最高级别的API)。 通常,使用/减less代码通常更容易,您还可以从将来向更高级别API引入的未来增强中获益。