NSOperation vs Grand Central Dispatch

Sun*_*day 454 concurrency nsoperation nsoperationqueue grand-central-dispatch ios

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

听起来像是两者,GCD并从用户那里NSOperationQueue抽象出明确的创造NSThreads.然而这两种方法之间的关系对我来说并不清楚,所以任何反馈都要赞赏!

BJ *_*mer 512

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

通常,您应该使用最适合您需求的抽象级别.这意味着您通常应该使用NSOperationQueue而不是GCD,除非您需要做一些NSOperationQueue不支持的事情.

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

警告:另一方面,如果你真的只需要发送一个块,并且不需要提供任何附加功能NSOperationQueue,那么使用GCD没有任何问题.确保它是适合这项工作的正确工具.

  • @Sandy实际上恰恰相反,NSOperation使用GCD(至少在iOS和OS X的更高版本中). (3认同)
  • @RajAggrawal是的,那行得通……但是您陷入了串行队列。NSOperation可以“在其他三个完成之后执行此操作,但同时执行所有其他操作”。操作依赖关系甚至可以存在于不同队列上的操作之间。大多数人不需要它,但是如果您这样做,则NSOperation将是一个更好的选择。 (2认同)

Bra*_*son 366

根据我对相关问题的回答,我将不同意BJ并建议你先看看GCD而不是NSOperation/NSOperationQueue,除非后者提供你需要GCD不需要的东西.

在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之前).

  • 我只是略微不同意; 我使用普通的GCD相当多.但我认为你在这个答案中过分重视NSBlockOperation.NSOperationQueue的所有好处(依赖性,可调试性等)也适用于块操作. (19认同)
  • @BJHomer - 我认为在我的情况下避免使用NSBlockOperation更多是个人偏好的问题,尽管在看到使用它们的开销拖累了几个应用程序之后我总是回避NSOperations.如果我要使用块,我倾向于全押GCD,除了我需要依赖支持的极少数例外. (3认同)

San*_*kar 94

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

GCD优于NSOperation:
i.实施
对于GCD实施来说,重量很轻,
NSOperationQueue很复杂,重量很重

NSOperation相对于GCD的优势:

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

II.依赖关系
可以建立两者之间的相关性NSOperations
操作将无法启动,直到其所有相关返回成品真.

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

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

什么时候去,GCD或者NSOperation
你想要更多地控制队列(所有上面提到的)使用NSOperation 和简单的情况,你想要更少的开销(你只是想在后台做一些工作,只需要很少的额外工作)使用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/

  • Vey很好的解释了!谢谢! (2认同)

eva*_*hin 34

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

通过NSOperation,KVO也是可能的.

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

  • 值得注意的是,如果你要取消的是加载图像的网络操作,那么你不需要`NSOperation`,因为`NSURLSessionTask.cancel`和`NSURLSession.invalidateAndCancel`提供了这个功能.一般来说,`NSURLSession`提供了一些`NSOperationQueue`的功能,因为`NSURLSessionTask`提供了一个`NSOperation`的一些功能. (4认同)

das*_*das 33

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

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

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


Sha*_*643 24

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

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

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

NSQueueOperation相对于GCD的优势:

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

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

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

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

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


gna*_*729 6

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

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


归档时间:

查看次数:

110049 次

最近记录:

8 年,10 月 前