(iOS) dispatch_async() 和 NSOperationQueue 的区别

50
我学习iOS编程感谢斯坦福的CS193p课程(在iTunes U上)以及Big Nerd Ranch的iOS编程书籍。两者都建议使用dispatch_async()dispatch_get_main_queue()等来处理线程和并发操作。然而,在WWDC 2012的会议中关于构建并发UI的演讲者推荐使用NSOperationQueuedispatch_*()NSOperationQueue之间有什么区别,是否有任何原因(技术、性能、风格或其他方面),我应该使用其中一个而不是另一个? NSOperationQueue只是围绕dispatch_async的Objective-C包装器,还是比那更多?

glasz的回答非常全面,但我必须指出的是如何选择使用什么。如果您想在保持范围的同时异步执行某些操作,则使用(块启用)gcd。但是,如果您有一个非常明确定义的任务,可重复使用且需要并发执行(以及类似任务),则应创建NSOperations,其中可以适当地管理特定于该任务的功能。这既可扩展又美观。 - geekay
4个回答

76

NSOperation*类是较高级别的API,它们将GCD的低级API隐藏起来,让你可以专注于完成任务。

经验法则是:首先使用最高级别的API,然后根据需要降级以完成任务

这种方法的优点是,你的代码最大程度地与供应商提供的具体实现无关。在这个例子中,使用NSOperation,你将使用苹果公司对执行队列的实现(使用GCD)。如果苹果公司决定在幕后更改实现细节,他们可以这样做而不会破坏你的应用程序代码。
一个这样的例子是苹果公司弃用GCD并使用完全不同的库(这是不太可能的,因为苹果公司创建了GCD,并且似乎每个人都喜欢它)。

关于这个问题,我建议咨询以下资源:

现在,针对您的具体问题:
什么是dispatch_*()和NSOperationQueue之间的区别[...],我应该使用其中一个还是另一个有任何原因(技术,性能,风格或其他)?
请参见上文。
NSOperationQueue只是dispatch_async的Objective-C封装,还是它比这更复杂?
是的,基本上就是这样。此外还包括操作依赖项,轻松启动/停止等功能。
修正:
首先使用最高级别的API听起来很有趣。当然,如果您需要快速在特定线程上运行代码,则不希望编写大量样板代码,使用较低级别的C函数完全有效。
dispatch_async(dispatch_get_main_queue(), ^{
  do_something();
});

但是请考虑这一点:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
  do_something();
}];

我建议选择后者,因为你将写的大部分内容都是Objective-C,所以为什么不接受它的表达能力呢?

12

NSOperationQueue比dispatch_async()更重,它仅以非常有限的方式基于GCD(实质上只使用全局调度队列来执行其异步操作,但没有使用其他GCD功能)。

NSOperationQueue具有GCD未提供的附加功能,但如果您不需要这些功能,使用GCD将会提供更好的性能。


10

它们都在做同样的事情,但它们之间的主要区别是:

  • 使用NSOperation,如果我们想要取消任务,则可以取消它,而如果我们使用GCD,则一旦将任务分配给队列,则无法取消它。

2

除了上面的回答之外,NSOperation队列相比GCD的另一个优点是:

1)依赖关系:我们可以在两个NSOperations之间建立依赖关系。只有当所有依赖项都返回true时,操作才会开始。

2)操作状态:我们可以监视操作或操作队列的状态。就绪、执行或完成

3)最大操作数:我们可以指定同时运行的最大排队操作数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接