(iOS)dispatch_async()与NSOperationQueue

时间:2012-07-26 19:27:03

标签: grand-central-dispatch nsoperationqueue

由于斯坦福大学的CS193p课程(在iTunes U上)以及Big Nerd Ranch的iOS编程书,我学习了iOS编程。在这两个方面,他们建议使用dispatch_async()dispatch_get_main_queue()等来处理线程和并发操作。但是,在WWDC 2012关于构建并发用户界面的会议上,发言人建议使用NSOperationQueue

dispatch_*()NSOperationQueue之间有什么区别,是否有任何理由(技术,性能,风格或其他方面)我应该使用另一个? NSOperationQueue只是dispatch_async周围的Objective-C包装器,还是比它更多?

4 个答案:

答案 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)最大操作次数: - 我们可以指定可以同时运行的最大排队操作数