为什么我应该选择GCD而非NSOperation并阻止高级应用程序?

Lio*_*Lio 31 concurrency objective-c grand-central-dispatch ios objective-c-blocks

Apple的Grand Central Dispatch参考文献称:

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

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

对于高级应用程序,我实际上无法想到这种情况,其中GCD的使用是强制性的,并且可以/不应该使用NSOperation.

有什么想法吗?

Bra*_*son 55

这里提出的观点与Chris Hanson在他的文章" 何时使用NSOperation vs. GCD "中所说的相同:

直截了当的答案是所有应用程序开发的一般准则:

始终使用可用的最高级抽象,并在测量显示需要时下拉到较低级抽象.

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

总的来说,我同意这一点.NSOperation和NSOperationQueue为依赖关系以及GCD块和队列所没有的一两个其他东西提供支持,并且它们抽象出了并发操作如何实现的低级细节.如果您需要该功能,NSOperation是一个非常好的方法.

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

第一个原因来自我的应用程序中的分析,我发现NSOperation对象分配和释放过程在处理小而频繁的操作时占用了大量的CPU资源,比如将OpenGL ES帧渲染到屏幕上.GCD块完全消除了这种开销,从而显着提高了性能.

第二个原因更主观,但我相信我的代码在使用块时比NSOperations更清晰.快速捕获块所允许的范围及其内联特性可以减少代码,因为您不需要创建自定义NSOperation子类或捆绑参数以传递给操作,在我看来,更具描述性的代码,因为您可以将代码放在队列中,在它被触发的位置运行.

同样,这是一个偏好问题,但我发现自己更多地使用GCD,即使在其他更抽象的Cocoa应用程序中也是如此.

  • 此外,从 2020 Swift 的角度来看,“Operation”和“OperationQueue”是“NSObject”类型(Objective-C 遗产),而“DispatchQueue”、“DispatchWorkItem”和“DispatchGroup”则不是。 (2认同)

Nit*_*rad 13

  • 首选GCD,其中任务不复杂,并且需要最佳的CPU性能.
  • 首选NSOperationQueue,其中任务很复杂,需要取消或暂停块和依赖关系管理.

GCD是一种表示将同时执行的工作单元的轻量级方法.你没有安排这些工作单位; 系统负责为您安排日程安排.在块之间添加依赖性可能是令人头疼的问 取消或暂停块会为开发人员创建额外的工作!

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

有关详细说明,请参阅此问题:NSOperation vs Grand Central Dispatch