我试图了解调度同步和调度异步,我知道它以GCD的同步和异步方式执行。但是当我尝试下面的代码时,它给了我奇怪的情况。
我在Playground和Sync块中执行了3次测试以下代码,而async块给出了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次同步块。以及为什么会出现NSException错误。
答案 0 :(得分:2)
同步将停止当前线程,直到完成您分配给它的任务。
异步将继续当前线程,并在当前线程之后或之后执行任务。
为什么会有意外的行为?
这是因为loadView()
希望在执行后将UIView分配给view
属性,而您正在使用async进行操作,它将在loadView完成后执行。
该异常可能是因为您没有按时分配UIView,或者是因为您正在私有队列中处理UI。用户界面应始终在主线程中处理。
您的变量que
是一个私有队列,并且由于未指定否则它指向后台线程。
像这样编辑代码可能会帮助您:
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()