50

得益于斯坦福大学的 CS193p 课程(在 iTunes U 上)以及 Big Nerd Ranch 的 iOS 编程书籍,我学习了 iOS 编程。在这两者中,他们建议使用dispatch_async(),dispatch_get_main_queue()等来处理线程和并发操作。然而,在 WWDC 2012 关于构建并发 UI 的会议上,演讲者建议使用NSOperationQueue.

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

4

4 回答 4

75

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,那么为什么不接受它的表现力呢?

于 2012-11-06T10:43:48.980 回答
12

NSOperationQueue 比 dispatch_async() 重得多,它只是以非常有限的方式基于 GCD(本质上它只是使用全局调度队列来执行其异步操作,但不使用其他 GCD 工具)。

NSOperationQueue 确实具有 GCD 未提供的其他功能,但如果您不需要这些功能,使用 GCD 将为您提供更好的性能。

于 2012-07-27T02:59:19.097 回答
10

他们都在做同样的事情,但他们之间的主要区别在于——我们可以在使用 NSOperation 时取消任务,而如果我们使用 GCD,那么一旦我们将任务分配到队列中,我们就无法取消它。

于 2013-08-29T07:18:51.317 回答
1

除了上面的答案,NSOperation 队列相对于 GCD 的另一个优势是

1) 依赖关系:- 我们可以在两个 NSOperations 之间建立一个依赖关系,直到它的所有依赖关系都为完成返回 true,操作才会开始。

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

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

于 2017-03-30T11:51:17.360 回答