我正在学习iOS的并发编程。到目前为止,我已经阅读了有关NSOperation
/NSOperationQueue
和的信息GCD
。使用NSOperationQueue
over 的原因是什么GCD
,反之亦然?
听起来既像GCD
又NSOperationQueue
抽象NSThreads
了用户的显式创建。但是,这两种方法之间的关系对我而言尚不清楚,因此请您提供任何反馈意见!
我正在学习iOS的并发编程。到目前为止,我已经阅读了有关NSOperation
/NSOperationQueue
和的信息GCD
。使用NSOperationQueue
over 的原因是什么GCD
,反之亦然?
听起来既像GCD
又NSOperationQueue
抽象NSThreads
了用户的显式创建。但是,这两种方法之间的关系对我而言尚不清楚,因此请您提供任何反馈意见!
Answers:
GCD
是基于C的低级API,可非常简单地使用基于任务的并发模型。NSOperation
并且NSOperationQueue
是做类似事情的Objective-C类。NSOperation
首次引入,但从10.5和iOS 2开始,NSOperationQueue
并且在内部使用实现了朋友GCD
。
通常,您应该使用适合您需求的最高级别的抽象。这意味着您通常应使用NSOperationQueue
而不是GCD
,除非您需要执行NSOperationQueue
不支持的操作。
请注意,NSOperationQueue
它不是GCD的“简化版本”;实际上,您可以做很多事情,NSOperationQueue
而pure却需要很多工作GCD
。(例如:带宽受限的队列一次只运行N个操作;建立操作之间的依赖关系。使用两者非常简单,使用。都NSOperation
非常困难GCD
。)Apple完成了利用GCD使用来创建非常好的对象友好的API的艰苦工作NSOperation
。充分利用他们的工作,除非您有理由不这样做。
警告:另一方面,如果您真的只需要发送一个块,并且不需要提供的任何其他功能NSOperationQueue
,那么使用GCD并没有错。只要确保它是完成这项工作的正确工具即可。
与我对一个相关问题的回答一致,我将不同意BJ的建议,建议您首先通过NSOperation / NSOperationQueue查看GCD,除非后者提供了您所需的GCD不需要的东西。
在使用GCD之前,我在应用程序中使用了很多NSOperations / NSOperationQueue来管理并发。但是,自从我开始定期使用GCD以来,几乎将NSOperations和NSOperationQueues完全替换为块和调度队列。这源于我在实践中使用这两种技术的方式以及我对它们进行的性能分析。
首先,使用NSOperations和NSOperationQueues会产生不小的开销。这些是可可对象,需要对其进行分配和释放。在我编写的一个iOS应用程序中,该应用程序以60 FPS渲染3-D场景,我使用NSOperations封装了每个渲染帧。当我对此进行概要分析时,这些NSOperation的创建和拆除占了正在运行的应用程序中CPU周期的很大一部分,并且正在减慢速度。我用简单的块和GCD串行队列替换了这些,然后开销消失了,从而显着提高了渲染性能。这不是我唯一注意到使用NSOperations产生开销的地方,而且我在Mac和iOS上都看到了这一点。
其次,基于块的调度代码具有优雅之处,使用NSOperations时很难匹配。将几行代码包装在一个块中并将其分派以在串行或并发队列上执行非常方便,其中创建自定义NSOperation或NSInvocationOperation来执行此操作需要更多支持代码。我知道您可以使用NSBlockOperation,但您最好将其分发到GCD。我认为,将这些代码包装在与应用程序中的相关处理内联的块中,比使用单独的方法或自定义的NSOperation封装这些任务可以更好地组织代码。
NSOperations和NSOperationQueue仍然有很好的用途。GCD没有真正的依赖关系概念,其中NSOperationQueues可以建立非常复杂的依赖关系图。在少数情况下,我会使用NSOperationQueues。
总的来说,虽然我通常主张使用最高级别的抽象来完成任务,但是在这种情况下,我主张使用GCD的较低级别的API。在我讨论过的iOS和Mac开发人员中,绝大多数选择使用NSOperations上的GCD,除非他们的目标是不支持它的OS版本(iOS 4.0和Snow Leopard之前的版本)。
GCD
是基于C的底层API。
NSOperation
并且NSOperationQueue
是Objective-C类。
NSOperationQueue
是目标C包装器GCD
。如果使用的是NSOperation,则隐式使用的是Grand Central Dispatch。
GCD优于NSOperation的优势:
i。实施
对于GCD
实施非常轻量级
NSOperationQueue
是复杂而繁重的
NSOperation相对于GCD的优势:
一世。控制操作时,
您可以暂停,取消,恢复NSOperation
ii。依赖关系
可以建立两者之间的相关性NSOperations
操作将无法启动,直到所有的依赖的成品返回true。
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/
NSOperation优于GCD的另一个原因是NSOperation的取消机制。例如,一个500px的应用程序显示了数十张照片,使用NSOperation可以在滚动表视图或集合视图时取消不可见图像单元的请求,这可以大大提高应用程序性能并减少内存占用。GCD无法轻松地支持这一点。
同样,通过NSOperation,可以实现KVO。
这是Eschaton的一篇文章,值得阅读。
NSOperation
这个,因为 NSURLSessionTask.cancel
和NSURLSession.invalidateAndCancel
提供此功能。通常,NSURLSession
提供了的某些功能NSOperationQueue
,以及NSURLSessionTask
提供了NSOperation
NSQueueOperations和GCD都可以通过释放UI应用程序主线程来在单独的线程中在后台执行繁重的计算任务。
好吧,根据之前的文章,我们看到NSOperations具有addDependency,因此您可以按顺序将操作逐个排队。
但我也了解了有关GCD串行队列的信息,您可以使用dispatch_queue_create在队列中创建运行操作。这将允许以顺序的方式一个接一个地运行一组操作。
NSQueueOperation相对于GCD的优势:
它允许添加依赖关系,并允许您删除依赖关系,因此对于一个事务,您可以使用依赖关系顺序运行,而对于其他事务,可以同时运行,而GCD不允许以这种方式运行。
如果操作在队列中,则很容易取消,如果正在运行,则可以将其停止。
您可以定义最大并发操作数。
您可以暂停他们在队列中的操作
您可以找到队列中有多少未决操作。
GCD非常易于使用-如果您想在后台执行某项操作,您所需要做的就是编写代码并将其分派到后台队列中。使用NSOperation做同样的事情是很多额外的工作。
NSOperation的优点是(a)您有一个可以向其发送消息的真实对象,并且(b)您可以取消NSOperation。那不是小事。您需要子类化NSOperation,必须正确编写代码,以便取消和正确完成任务都可以正常工作。因此,对于简单的事情,您可以使用GCD,对于更复杂的事情,您可以创建NSOperation的子类。(有子类NSInvocationOperation和NSBlockOperation,但是它们所做的一切都可以通过GCD轻松完成,因此没有充分的理由使用它们)。
好吧,NSOperations只是建立在Grand Central Dispatch之上的API。因此,当您使用NSOperations时,您实际上仍在使用Grand Central Dispatch。NSOperations只是为您提供了一些您可能想要的精美功能。您可以使某些操作依赖于其他操作,在对项目加总后对队列进行重新排序,以及类似的事情。实际上,ImageGrabber已经在使用NSOperations和操作队列!ASIHTTPRequest在后台使用它们,并且您可以根据需要配置用于不同行为的操作队列。那么您应该使用哪个呢?无论哪种对您的应用程序有意义。对于此应用程序,它非常简单,因此我们直接使用了Grand Central Dispatch,无需使用NSOperation的精美功能。但是,如果您的应用需要它们,请随时使用!