ios NSOperation 与 Grand Central Dispatch
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10373331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NSOperation vs Grand Central Dispatch
提问by SundayMonday
I'm learning about concurrent programming for iOS. So far I've read about NSOperation
/NSOperationQueue
and GCD
. What are the reasons for using NSOperationQueue
over GCD
and vice versa?
我正在学习了解iOS并发编程。到目前为止,我已经阅读了NSOperation
/NSOperationQueue
和GCD
. 使用NSOperationQueue
overGCD
反之亦然的原因是什么?
Sounds like both GCD
and NSOperationQueue
abstract away the explicit creation of NSThreads
from the user. However the relationship between the two approaches isn't clear to me so any feedback to appreciated!
听起来既像GCD
又NSOperationQueue
抽象NSThreads
了用户的显式创建。然而,我不清楚这两种方法之间的关系,所以任何反馈都值得赞赏!
回答by BJ Homer
GCD
is a low-level C-based API that enables very simple use of a task-based concurrency model. NSOperation
and NSOperationQueue
are Objective-C classes that do a similar thing. NSOperation
was introduced first, but as of 10.5and iOS 2, NSOperationQueue
and friends are internally implemented using GCD
.
GCD
是一个基于 C 的低级 API,可以非常简单地使用基于任务的并发模型。NSOperation
并且NSOperationQueue
是执行类似操作的 Objective-C 类。NSOperation
最先引入,但从10.5和iOS 2 开始,NSOperationQueue
朋友们在内部使用GCD
.
In general, you should use the highest level of abstraction that suits your needs. This means that you should usually use NSOperationQueue
instead of GCD
, unless you need to do something that NSOperationQueue
doesn't support.
通常,您应该使用适合您需要的最高抽象级别。这意味着您通常应该使用NSOperationQueue
而不是GCD
,除非您需要做一些NSOperationQueue
不支持的事情。
Note that NSOperationQueue
isn't a "dumbed-down" version of GCD; in fact, there are many things that you can do very simply with NSOperationQueue
that take a lot of work with pure GCD
. (Examples: bandwidth-constrained queues that only run N operations at a time; establishing dependencies between operations. Both very simple with NSOperation
, very difficult with GCD
.) Apple's done the hard work of leveraging GCD to create a very nice object-friendly API with NSOperation
. Take advantage of their work unless you have a reason not to.
请注意,这NSOperationQueue
不是 GCD 的“简化版”;事实上,有很多事情你可以很简单地做NSOperationQueue
,而 pure 需要做很多工作GCD
。(示例:带宽受限的队列,一次只运行 N 个操作;建立操作之间的依赖关系。两者都非常简单,使用NSOperation
,使用起来非常困难GCD
。)Apple 完成了利用 GCD 创建非常好的对象友好 API 和 的艰苦工作NSOperation
。除非您有理由不这样做,否则请利用他们的工作。
Caveat:
On the other hand, if you really just need to send off a block, and don't need any of the additional functionality that NSOperationQueue
provides, there's nothing wrong with using GCD. Just be sure it's the right tool for the job.
警告:另一方面,如果您真的只需要发送一个块,并且不需要提供的任何附加功能NSOperationQueue
,那么使用 GCD 没有任何问题。只要确保它是适合这项工作的工具。
回答by Brad Larson
In line with my answer to a related question, I'm going to disagree with BJ and suggest you first look at GCD over NSOperation / NSOperationQueue, unless the latter provides something you need that GCD doesn't.
根据我对相关问题的回答,我将不同意 BJ 并建议您首先通过 NSOperation / NSOperationQueue 来查看 GCD,除非后者提供了 GCD 没有的您需要的东西。
Before GCD, I used a lot of NSOperations / NSOperationQueues within my applications for managing concurrency. However, since I started using GCD on a regular basis, I've almost entirely replaced NSOperations and NSOperationQueues with blocks and dispatch queues. This has come from how I've used both technologies in practice, and from the profiling I've performed on them.
在 GCD 之前,我在我的应用程序中使用了很多 NSOperations / NSOperationQueues 来管理并发。然而,自从我开始定期使用 GCD,我几乎完全用块和调度队列替换了 NSOperations 和 NSOperationQueues。这来自于我在实践中使用这两种技术的方式,以及我对它们进行的分析。
First, there is a nontrivial amount of overhead when using NSOperations and NSOperationQueues. These are Cocoa objects, and they need to be allocated and deallocated. In an iOS application that I wrote which renders a 3-D scene at 60 FPS, I was using NSOperations to encapsulate each rendered frame. When I profiled this, the creation and teardown of these NSOperations was accounting for a significant portion of the CPU cycles in the running application, and was slowing things down. I replaced these with simple blocks and a GCD serial queue, and that overhead disappeared, leading to noticeably better rendering performance. This wasn't the only place where I noticed overhead from using NSOperations, and I've seen this on both Mac and iOS.
首先,在使用 NSOperations 和 NSOperationQueues 时有一个不小的开销。这些是 Cocoa 对象,它们需要被分配和释放。在我编写的以 60 FPS 渲染 3-D 场景的 iOS 应用程序中,我使用 NSOperations 来封装每个渲染的帧。当我对此进行分析时,这些 NSOperations 的创建和拆除占了正在运行的应用程序中 CPU 周期的很大一部分,并且会减慢速度。我用简单的块和 GCD 串行队列替换了这些,并且开销消失了,从而显着提高了渲染性能。这不是我注意到使用 NSOperations 产生开销的唯一地方,我在 Mac 和 iOS 上都看到了这一点。
Second, there's an elegance to block-based dispatch code that is hard to match when using NSOperations. It's so incredibly convenient to wrap a few lines of code in a block and dispatch it to be performed on a serial or concurrent queue, where creating a custom NSOperation or NSInvocationOperation to do this requires a lot more supporting code. I know that you can use an NSBlockOperation, but you might as well be dispatching something to GCD then. Wrapping this code in blocks inline with related processing in your application leads in my opinion to better code organization than having separate methods or custom NSOperations which encapsulate these tasks.
其次,在使用 NSOperations 时很难匹配基于块的调度代码的优雅。将几行代码包装在一个块中并分派它以在串行或并发队列上执行是非常方便的,其中创建自定义 NSOperation 或 NSInvocationOperation 来执行此操作需要更多的支持代码。我知道你可以使用 NSBlockOperation,但你可能会向 GCD 发送一些东西。在我看来,将这些代码包装在与应用程序中相关处理内联的块中,比使用单独的方法或封装这些任务的自定义 NSOperations 更好地组织代码。
NSOperations and NSOperationQueues still have very good uses. GCD has no real concept of dependencies, where NSOperationQueues can set up pretty complex dependency graphs. I use NSOperationQueues for this in a handful of cases.
NSOperations 和 NSOperationQueues 仍然有很好的用途。GCD 没有真正的依赖概念,其中 NSOperationQueues 可以设置非常复杂的依赖关系图。在少数情况下,我为此使用 NSOperationQueues。
Overall, while I usually advocate for using the highest level of abstraction that accomplishes the task, this is one case where I argue for the lower-level API of GCD. Among the iOS and Mac developers I've talked with about this, the vast majority choose to use GCD over NSOperations unless they are targeting OS versions without support for it (those before iOS 4.0 and Snow Leopard).
总的来说,虽然我通常主张使用最高级别的抽象来完成任务,但这是我主张 GCD 的较低级别 API 的一种情况。在我与之讨论过的 iOS 和 Mac 开发人员中,绝大多数选择使用 GCD 而不是 NSOperations,除非他们针对的是不支持它的操作系统版本(iOS 4.0 和 Snow Leopard 之前的版本)。
回答by Sangram Shivankar
GCD
is a low-level C-based API.NSOperation
and NSOperationQueue
are Objective-C classes.NSOperationQueue
is objective C wrapper over GCD
.
If you are using NSOperation, then you are implicitly using Grand Central Dispatch.
GCD
是一个基于 C 的低级 API。NSOperation
并且NSOperationQueue
是Objective-C 类。NSOperationQueue
是目标 C 包装器GCD
。如果您使用的是 NSOperation,那么您就是在隐式使用Grand Central Dispatch。
GCD advantage over NSOperation:
i. implementation
For GCD
implementation is very light-weightNSOperationQueue
is complex and heavy-weight
GCD 相对于 NSOperation 的优势:
i. 实现
对于GCD
实现很轻量级NSOperationQueue
是复杂和重量级的
NSOperation advantages over GCD:
NSOperation 相对于 GCD 的优势:
i. Control On Operation
you can Pause, Cancel, Resume an NSOperation
一世。控制操作,
您可以暂停、取消、恢复NSOperation
ii. Dependencies
you can set up a dependency between two NSOperations
operation will not started until all of its dependencies return true for finished.
ii. 依赖关系
你可以在两个NSOperations
操作之间设置一个依赖关系,直到它的所有依赖关系都返回true表示完成。
iii. State of Operation
can monitor the state of an operation or operation queue.
ready ,executing or finished
三、State of Operation
可以监视操作或操作队列的状态。准备、执行或完成
iv. Max Number of Operation
you can specify the maximum number of queued operations that can run simultaneously
四、Max Number of Operation
您可以指定可以同时运行的最大排队操作数
When to Go for GCD
or NSOperation
when you want more control over queue (all above mentioned) use NSOperation
and for simple cases where you want less overhead
(you just want to do some work "into the background" with very little additional work) use GCD
何时开始GCD
或NSOperation
何时您想要更多地控制队列(上述所有内容)使用NSOperation
以及对于您希望减少开销的简单情况(您只想做一些“进入后台”的工作,而几乎没有额外的工作)使用GCD
ref:
https://cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperationqueue.htmlhttp://nshipster.com/nsoperation/
参考:
https : //cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/ http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperationqueue.html http ://nshipster.com/nsoperation/
回答by evanchin
Another reason to prefer NSOperation over GCD is the cancelation mechanism of NSOperation. For example, an App like 500px that shows dozens of photos, use NSOperation we can cancel requests of invisible image cells when we scroll table view or collection view, this can greatly improve App performance and reduce memory footprint. GCD can't easily support this.
另一个比 GCD 更喜欢 NSOperation 的原因是 NSOperation 的取消机制。比如像500px这样显示几十张照片的App,使用NSOperation我们可以在滚动table view或者collection view的时候取消不可见的图片单元格的请求,这样可以大大提高App的性能,减少内存占用。GCD 不能轻易支持这一点。
Also with NSOperation, KVO can be possible.
同样使用 NSOperation,KVO 也是可能的。
Hereis an article from Eschaton which is worth reading.
这是来自 Eschaton 的一篇文章,值得一读。
回答by das
GCD is indeed lower-level than NSOperationQueue, its major advantage is that its implementation is very light-weight and focused on lock-free algorithms and performance.
GCD 确实比 NSOperationQueue 低级,它的主要优点是它的实现非常轻量级,并且专注于无锁算法和性能。
NSOperationQueue does provide facilities that are not available in GCD, but they come at non-trivial cost, the implementation of NSOperationQueue is complex and heavy-weight, involves a lot of locking, and uses GCD internally only in a very minimal fashion.
NSOperationQueue 确实提供了 GCD 中没有的功能,但它们的成本非常高,NSOperationQueue 的实现复杂且重量级,涉及大量锁定,并且仅以极少的方式在内部使用 GCD。
If you need the facilities provided by NSOperationQueue by all means use it, but if GCD is sufficient for your needs, I would recommend using it directly for better performance, significantly lower CPU and power cost and more flexibility.
如果您一定需要 NSOperationQueue 提供的功能,请使用它,但如果 GCD 足以满足您的需求,我建议直接使用它以获得更好的性能,显着降低 CPU 和功耗成本以及更大的灵活性。
回答by Shashi3456643
Both NSQueueOperations and GCD allow executing heavy computation task in the background on separate threads by freeing the UI Application Main Tread.
NSQueueOperations 和 GCD 都允许通过释放 UI 应用程序主线程在单独的线程上在后台执行繁重的计算任务。
Well, based previous post we see NSOperations has addDependency so that you can queue your operation one after another sequentially.
好吧,基于上一篇文章,我们看到 NSOperations 具有 addDependency,因此您可以按顺序将操作一个接一个地排队。
But I also read about GCD serial Queues you can create run your operations in the queue using dispatch_queue_create. This will allow running a set of operations one after another in a sequential manner.
但我也阅读了有关 GCD 串行队列的信息,您可以使用 dispatch_queue_create 在队列中创建运行您的操作。这将允许以顺序方式一个接一个地运行一组操作。
NSQueueOperation Advantages over GCD:
NSQueueOperation 优于 GCD:
It allows to add dependency and allows you to remove dependency so for one transaction you can run sequential using dependency and for other transaction run concurrently while GCD doesn't allow to run this way.
It is easy to cancel an operation if it is in the queue it can be stopped if it is running.
You can define the maximum number of concurrent operations.
You can suspend operation which they are in Queue
You can find how many pending operations are there in queue.
它允许添加依赖项并允许您删除依赖项,因此对于一个事务,您可以使用依赖项顺序运行,而对于其他事务并发运行,而 GCD 不允许以这种方式运行。
如果某个操作在队列中,则很容易取消它,如果它正在运行,则可以将其停止。
您可以定义并发操作的最大数量。
您可以暂停它们在队列中的操作
您可以找到队列中有多少挂起的操作。
回答by gnasher729
GCD is very easy to use - if you want to do something in the background, all you need to do is write the code and dispatch it on a background queue. Doing the same thing with NSOperation is a lot of additional work.
GCD 非常容易使用——如果你想在后台做一些事情,你需要做的就是编写代码并在后台队列中调度它。用 NSOperation 做同样的事情是很多额外的工作。
The advantage of NSOperation is that (a) you have a real object that you can send messages to, and (b) that you can cancel an NSOperation. That's not trivial. You need to subclass NSOperation, you have to write your code correctly so that cancellation and correctly finishing a task both work correctly. So for simple things you use GCD, and for more complicated things you create a subclass of NSOperation. (There are subclasses NSInvocationOperation and NSBlockOperation, but everything they do is easier done with GCD, so there is no good reason to use them).
NSOperation 的优点是 (a) 您有一个可以向其发送消息的真实对象,以及 (b) 您可以取消 NSOperation。这不是小事。您需要继承 NSOperation,您必须正确编写代码,以便取消和正确完成任务都能正常工作。所以对于简单的事情你使用 GCD,对于更复杂的事情你创建一个 NSOperation 的子类。(有子类 NSInvocationOperation 和 NSBlockOperation,但它们所做的一切都可以通过 GCD 轻松完成,因此没有充分的理由使用它们)。
回答by Ankul Gaur
Well, NSOperations are simply an API built on top of Grand Central Dispatch. So when you're using NSOperations, you're really still using Grand Central Dispatch. It's just that NSOperations give you some fancy features that you might like. You can make some operations dependent on other operations, reorder queues after you sumbit items, and other things like that. In fact, ImageGrabber is already using NSOperations and operation queues! ASIHTTPRequest uses them under the hood, and you can configure the operation queue it uses for different behavior if you'd like. So which should you use? Whichever makes sense for your app. For this app it's pretty simple so we just used Grand Central Dispatch directly, no need for the fancy features of NSOperation. But if you need them for your app, feel free to use it!
好吧,NSOperations 只是一个建立在 Grand Central Dispatch 之上的 API。因此,当您使用 NSOperations 时,您实际上仍在使用 Grand Central Dispatch。只是 NSOperations 为您提供了一些您可能喜欢的奇特功能。您可以使某些操作依赖于其他操作,在您提交项目后重新排序队列,以及其他类似的事情。事实上,ImageGrabber 已经在使用 NSOperations 和操作队列了!ASIHTTPRequest 在幕后使用它们,如果您愿意,您可以配置它用于不同行为的操作队列。所以,你应该使用它?哪个对您的应用程序有意义。对于这个应用程序,它非常简单,所以我们直接使用了 Grand Central Dispatch,不需要 NSOperation 的花哨功能。但是,如果您的应用程序需要它们,请随时使用它!