10

有时我必须在主线程上做一些事情,并建议将代码放在OperationQueue.main.addOperation.

其他时候,建议在里面写代码DispatchQueue.main.async

这两者有什么区别?

(有一个类似的问题标题,但内容不匹配。)

4

2 回答 2

5

当我在主线程中执行任何任务(例如 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()
于 2019-09-30T05:33:23.433 回答
1

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 的回答,但这是一个值得商榷的话题。

NSOperation vs Grand Central Dispatch

于 2019-10-03T21:10:50.823 回答