由于斯坦福大学的CS193p课程(在iTunes U上)以及Big Nerd Ranch的iOS编程书,我学习了iOS编程。在这两个方面,他们建议使用dispatch_async()
,dispatch_get_main_queue()
等来处理线程和并发操作。但是,在WWDC 2012关于构建并发用户界面的会议上,发言人建议使用NSOperationQueue
。
dispatch_*()
和NSOperationQueue
之间有什么区别,是否有任何理由(技术,性能,风格或其他方面)我应该使用另一个? NSOperationQueue
只是dispatch_async
周围的Objective-C包装器,还是比它更多?
答案 0 :(得分:74)
NSOperation*
类是更高级别的api。他们隐藏GCD的低级API,以便您可以集中精力完成任务。
经验法则是:首先使用最高级别的api,然后根据您需要完成的内容降级。
这种方法的优点是您的代码对供应商提供的特定实现最为不可知。
在此示例中,使用NSOperation
,您将使用Apple的执行排队实现(使用GCD)。如果Apple决定在幕后改变实施细节,他们可以在不破坏您的应用程序代码的情况下这样做
一个这样的例子就是Apple贬低GCD并使用完全不同的库(这不太可能,因为Apple创建了GCD并且每个人似乎都喜欢它)。
关于此事,我建议咨询以下资源:
现在,关于您的具体问题:
dispatch _ *()和NSOperationQueue之间有什么区别,[...]
见上文。
[...]是否有任何理由(技术,表现,风格或其他方面)我应该使用其中一个?
如果NSOperation
内容完成了您的工作,请使用它。
NSOperationQueue只是一个围绕dispatch_async的Objective-C包装器,还是有更多呢?
是的,它基本上是。还有诸如操作依赖性,易于启动/停止等功能。
要说,首先使用最高级别的api可能听起来很有趣。当然,如果你需要一种快速的方法来在特定的线程上运行代码,你不需要编写大量的样板代码,这使得低级C函数的使用完全有效:
dispatch_async(dispatch_get_main_queue(), ^{
do_something();
});
但是考虑一下:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
do_something();
}];
我推荐后者,因为你写的大部分内容都是Objective-C,所以为什么不接受它的表现力呢?
答案 1 :(得分:10)
NSOperationQueue比dispatch_async()重得多,它只是以非常有限的方式基于GCD(实质上它只是使用全局调度队列来执行其异步操作,但不使用其他GCD工具)。
NSOperationQueue确实具有GCD未提供的其他功能,但如果您不需要这些功能,使用GCD将为您提供更好的性能。
答案 2 :(得分:9)
他们两人都在做同样的事情,但他们之间的主要区别在于 - 我们可以在使用NSOperation时取消任务,而如果我们使用GCD,那么一旦我们将任务分配到队列,那么我们就无法取消它。
答案 3 :(得分:1)
除上述答案外,NSOperation队列优于GCD的另一个优点是
1)依赖关系: - 我们可以在两个NSOperations之间建立依赖关系 在完成所有依赖关系返回true之前,操作不会启动。
2)操作状态: - 我们可以监视操作或操作队列的状态。准备,执行或完成
3)最大操作次数: - 我们可以指定可以同时运行的最大排队操作数