有时我必须在主线程上做一些事情,并建议将代码放在OperationQueue.main.addOperation
.
其他时候,建议在里面写代码DispatchQueue.main.async
。
这两者有什么区别?
(有一个类似的问题标题,但内容不匹配。)
有时我必须在主线程上做一些事情,并建议将代码放在OperationQueue.main.addOperation
.
其他时候,建议在里面写代码DispatchQueue.main.async
。
这两者有什么区别?
(有一个类似的问题标题,但内容不匹配。)
当我在主线程中执行任何任务(例如 Update my APP UI )时,我使用了“DispatchQueue.main.async”。当您需要在主线程中运行进一步的操作或阻塞时,您可以使用“OperationQueue”。查看本文以了解有关OperationQueue的更多信息
Apple Doc 中的OperationQueue
NSOperationQueue 类规范一组 Operation 对象的执行。被添加到队列后,操作将保留在该队列中,直到它被显式取消或完成其任务的执行。队列中的操作(但尚未执行)本身根据优先级和互操作对象依赖性进行组织,并相应地执行。一个应用程序可以创建多个操作队列并向其中的任何一个提交操作。
例子 :
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
activityIndicator.startAnimating()
calculate()
}
private func calculate() {
let queue = OperationQueue()
let blockOperation = BlockOperation {
var result = 0
for i in 1...1000000000 {
result += i
}
OperationQueue.main.addOperation {
self.activityIndicator.stopAnimating()
self.label.text = "\(result)"
self.label.isHidden = false
}
}
queue.addOperation(blockOperation)
}
}
来自 Apple Doc 的DispatchQueue
DispatchQueue 管理工作项的执行。提交到队列的每个工作项都在系统管理的线程池上进行处理。
例子 :
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
do {
let heroes = try JSONDecoder().decode([HeroStats].self, from: data)
DispatchQueue.main.async {
self.heroes = heroes
completed()
}
} catch let error {
print(error)
}
}.resume()
OperationQueue 只是 Grand Central Dispatch (GCD / libdispatch) 的一个客观 C 包装器。
如果您使用的是 OperationQueue,那么您就是在隐式使用 Grand Central Dispatch。
OperationQueue.main.addOperation 因此在后台使用 DispatchQueue.main.async。在 C API (GCD) 上使用 Objective C (OperationQueue) 会有一些开销,因此使用 GCD 会有轻微的性能提升。
我建议阅读 Brad Larson 关于为什么他更喜欢 GCD 而不是 OperationQueue 的回答,但这是一个值得商榷的话题。