使用NSOperation还是GCD
在Mac OS X雪豹系统中(iOS4中也新增了GCD)增加了有许多并发机制。除了run loop,线程(包括Cocoa和POSIX),Operation之外,雪豹添加了GrandCentral Dispatch (GCD),拥有非常轻量级的工作单元和并发方式,并且由系统决定其最佳调度方式。
但是,等等,我们不是已经有NSOperation了吗?对于你熟悉的NSOperation,在雪豹系统里就是基于GCD之上的,对此你不应该感到惊讶。然而,NSOperation和GCD还是有很多不同之处的,因此人们会有这样的疑惑:我应该什么时候决定用哪个呢?
简单的回答是遵循所有的应用程序开发的一般准则:当需要做出选择的时候,在你的可选方案里,始终选择使用最高级别的抽象,放弃使用较低层次的抽象。
在这种特定情况下,这意味着如果写Cocoa应用,你应该总是使用NSOperation而不是直接使用GCD。不是因为它们在效率方面的差别,而是因为NSOperation比GCD提供了更高级别的抽象。
例如,你可以设置两个NSOperation的依赖,让第二个NSOperation在第一个运行完成后才开始运行,尽管他们运行在不同的队列中。如果先创建了可以被取消的operation,你可以使用KVO来观察不同operation的完成(或取消)情况。你也可以设置一个block在应用完成后运行。当然,也可以使用NSBlockOperation来创建block。
你还可以使用Cocoa的NSOperation实现更高层的代码。如果你看过雪豹的新API里面的NSNotificationCenter,你会看到notification中使用NSOperationQueue来运行block。
最终,使用NSOperation代替GCD会稍微多一点开销,但一旦你开始使用operation,你将获得显著的有用的额外功能。使用NSOperation最大的好处在于:你可以拆分你的应用的工作单元,不仅运行在队列中,也可以取消,观察和设置依赖。NSOperation能让你很轻松的定义数据依赖,确保不仅仅是简单的串行运行你的代码,而且还没有死锁之类的副作用。
原文如下:
When to use NSOperation vs. GCD
Mac OS X has a number of concurrency mechanisms, and thatincreases with Snow Leopard. In addition to run loops, threads (both Cocoa andPOSIX) and operations, Snow Leopard addsGrand Central Dispatch (GCD), avery lightweight way to represent units of work and the style of concurrencythey need, and have the system figure out how to schedule them.
But wait, don’t we have that already in NSOperation? Itshouldn’t surprise you in the least to learn that NSOperation, on Snow Leopard,is built atop GCD. However, there are a number of differences between the two,and for that reason people have started to ask “How should I decide which touse when?”
The straightforward answer is a general guideline for allapplication development:
Always use the highest-level abstractionavailable to you, and drop down to lower-level abstractions when measurementshows that they are needed.
In this particular case, it means that when writing Cocoaapplications, you should generally be using NSOperation rather than using GCDdirectly. Not because of a difference in efficiency, but because NSOperationprovides a higher-level abstraction atop the mechanisms of GCD.
For example, you can set up a dependency between twoNSOperations such that the second will only be run after the first is complete— even if they’re run on different queues. You can use KVO to observe thecompletion (or cancellation) of different operations — and you can createoperations that support being cancelled in the first place. You can set acompletion block to run after an application has finished. And you can, ofcourse, create operations from blocks using NSBlockOperation.
You’ll also fit in better with Cocoa by using NSOperationin your high-level code. If you take a look at new Snow Leopard API onNSNotificationCenter, you’ll see one where you specify the NSOperationQueue onwhich you wish a notification to run a block.
Ultimately, you spend a little bit ofoverhead to use NSOperation instead of GCD, but you gain significant additionalfunctionality that will be useful as you start to compose operations together.And that’s the biggest benefit of NSOperation: You can break up yourapplication in terms of units of work that can not only be run on a queue, butalso canceled, observed, and depended upon. This lets you easily define yourdata dependencies and ensure that you aren’t simply running code serially as aside-effect of locking.