2016-11-23 14 views
11

当你需要在网络任务或操作,完成块执行主线程上一些东西,这些途径获得这将是最合适的,为什么?:OperationQueue.main VS DispatchQueue.main

  • OperationQueue.main.addOperation
  • DispatchQueue.main.async
+0

检查这个链接 - http://stackoverflow.com/questions/7651551/why-should-i-choose-gcd-over-nsoperation-and-blocks-for - 高级应用程序/ 7654476#7654476和http://stackoverflow.com/questions/10373331/nsoperation-vs-grand-central-dispatch – Rajat

回答

4

DispatchQueue管理的工作项目的执行。提交给队列的每个工作项都在由系统管理的线程池上处理。

参考:Apple Doc

的NSOperationQueue类规定了一组操作对象的执行。在添加到队列后,操作将保留在该队列中,直到它被明确取消或完成其任务。队列中的操作(但尚未执行)本身根据优先级和操作间对象依赖性进行组织,并相应执行。应用程序可能会创建多个操作队列并将操作提交给它们中的任何一个。

参考:Apple Doc

所以,你应该更喜欢DispatchQueue.main.async时要执行从任何网络电话会议结束块主线程的东西。特别是当它与UI Updates相关!如果你的任务很复杂,我的意思是如果你需要在运行任务上进一步操作,那么你可以用OperationQueue.main.addOperation,否则DispatchQueue.main.async会给出比较优化的性能!

+0

这并不回答他们应该选择哪个队列的问题。 – MrMage

+0

@MrMage是的,编辑答案一点点! – Lion

8

有关这两种队列之间差异的详细信息,请参阅Lion的答案。

这两种方法都行得通。但是,当需要更高级的调度(包括依赖关系,取消等)时,主要需要NSOperation。所以在这种情况下,一个简单的

DispatchQueue.main.async { /* do work */ } 

将会很好。这将相当于

dispatch_async(dispatch_get_main_queue(), ^{ /* do work */ }); 
在Objective-C,这也是我怎么会干这种语言

+1

@Lion:我不同意你选择用反编码格式化所有强调的单词作为代码。请考虑使用下划线来替代_italic_。 – MrMage

6

当使用的NSOperation

NSOperation API是伟大的封装的功能定义良好的块。例如,您可以使用NSOperation子类来封装应用程序的登录序列。

依赖管理是蛋糕上的锦上添花。一个操作可以依赖于其他操作,这是Grand Central Dispatch缺乏的强大功能。如果您需要以特定顺序执行多项任务,那么操作是一个很好的解决方案。

如果您要在短时间内创建几十个操作,则可能会出现操作失策。由于NSOperation API固有的开销,这可能导致性能问题。

当使用大中央调度

Grand Central Dispatch是理想的,如果你只需要一个代码块派遣到串行或并行队列。

如果您不想为繁琐的任务创建NSOperation subclass的麻烦,那么Grand Central Dispatch是一个很好的选择。 Grand Central Dispatch的另一个好处是您可以将相关的代码放在一起。看看下面的例子。

let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in 
// Process Response 
... 

dispatch_async(dispatch_get_main_queue(), {() -> Void in 
    // Update User Interface 
    ... 
}) 
}) 

在数据任务的完成处理程序,我们处理响应和通过调度闭合(或块)在主队列更新用户界面。这是必要的,因为我们不知道完成处理程序在哪个线程上执行,它很可能是后台线程。

this source逐字引用

相关问题