当您需要在网络任务或操作的完成块中的主线程上执行某些操作时,哪种方式获取它将是最合适的,为什么?:
OperationQueue.main.addOperation
DispatchQueue.main.async
答案 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
...
})
})
在数据任务的完成处理程序中,我们处理响应并通过将闭包(或块)分派给主队列来更新用户界面。这是必要的,因为我们不知道执行完成处理程序的线程,并且很可能是后台线程。
逐字引用
答案 2 :(得分:8)
DispatchQueue管理工作项的执行。提交到队列的每个工作项都在系统管理的线程池上处理。
参考:Apple Doc
NSOperationQueue类调节一组Operation对象的执行。添加到队列后,操作将保留在该队列中,直到明确取消或完成其任务为止。队列内的操作(但尚未执行)本身根据优先级和操作间对象依赖性进行组织,并相应地执行。应用程序可以创建多个操作队列并向其中任何一个提交操作。
参考:Apple Doc
因此,当您想要从任何网络调用的完成块在主线程上执行某些操作时,您应该更喜欢DispatchQueue.main.async
。特别是当它与UI Updates
有关时!如果您的任务很复杂,我的意思是如果您需要进一步操作运行任务,那么您可以使用OperationQueue.main.addOperation
,否则DispatchQueue.main.async
将提供相对更优的性能!