我试图了解 Dispatch Sync 和 Dispatch Async,我知道它以 GCD 的同步和异步方式执行。但是当我尝试下面的代码时,它给了我奇怪的场景。
我在 Playground 和同步块(synchronized block)中测试了以下代码执行了 3 次,异步 block 给出了 NSException。
//:一个基于 UIKit 的 Playground,用于呈现用户界面
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let que = DispatchQueue.init(label: "testing")
// Executed 3 times
que.sync {
for i in 0...10 {
print(i)
}
}
// Giving me NSException
que.async {
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.text = "Hello World!"
label.textColor = .black
view.addSubview(label)
self.view = view
print("Label Added to Text View")
}
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
为什么会执行3次sync block。以及为什么会出现 NSException 错误。
最佳答案
Sync 将停止当前线程,直到它完成您分配给它的任务。
Async 将继续当前线程并并行或在当前线程之后执行任务。
为什么它有意想不到的行为?
那是因为 loadView()
期望在它被执行后将一个 UIView 分配给 view
属性,你正在使用异步执行它,这将是在 loadView 完成后执行。
异常可能是因为您没有按时分配 UIView 或因为您正在处理私有(private)队列中的 UI。 UI 应始终在主线程中处理。
你的变量 que
是一个私有(private)队列,因为你没有指定它指向一个后台线程。
像这样编辑您的代码可能会帮助您:
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let que = DispatchQueue.init(label: "testing")
// Executed 3 times
que.sync {
for i in 0...10 {
print(i)
}
}
// Giving me NSException
DispatchQueue.main.async {
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.text = "Hello World!"
label.textColor = .black
view.addSubview(label)
print("Label Added to Text View")
}
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
关于ios - DispatchQueue.sync 与 DispatchQueue.async 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54649297/