OperationQueue.main vs DispatchQueue.main

时间:2016-11-23 12:07:06

标签: ios swift grand-central-dispatch nsoperationqueue ui-thread

当您需要在网络任务或操作的完成块中的主线程上执行某些操作时,哪种方式获取它将是最合适的,为什么?:

  • OperationQueue.main.addOperation
  • DispatchQueue.main.async

3 个答案:

答案 0 :(得分:13)

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

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

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

会没事的。这相当于

dispatch_async(dispatch_get_main_queue(), ^{ /* do work */ });

在Objective-C中,我也是用这种语言来做的。

答案 1 :(得分:10)

何时使用NSOperation

NSOperation API非常适合封装定义明确的功能块。例如,您可以使用NSOperation子类来封装应用程序的登录序列。

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

如果您在短时间内创建了数十项操作,则可以过度操作。由于NSOperation API固有的开销,这可能会导致性能问题。

何时使用Grand Central Dispatch

如果您只需要将一段代码分派给串行或并发队列,那么

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

逐字引用

答案 2 :(得分:8)

  

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

参考:Apple Doc

  

NSOperationQueue类调节一组Operation对象的执行。添加到队列后,操作将保留在该队列中,直到明确取消或完成其任务为止。队列内的操作(​​但尚未执行)本身根据优先级和操作间对象依赖性进行组织,并相应地执行。应用程序可以创建多个操作队列并向其中任何一个提交操作。

参考:Apple Doc

因此,当您想要从任何网络调用的完成块在主线程上执行某些操作时,您应该更喜欢DispatchQueue.main.async。特别是当它与UI Updates有关时!如果您的任务很复杂,我的意思是如果您需要进一步操作运行任务,那么您可以使用OperationQueue.main.addOperation,否则DispatchQueue.main.async将提供相对更优的性能!