[英]Swift Threading: When to use DispatchQueue.main.async?
我相信当我调用它时我明白调度队列在做什么,但我不确定我应该在什么时候使用它以及当我使用它时它的优点是什么。
如果我的理解是正确的, DispatchQueue.main.async { // code }
将调度包含在闭包中的代码以异步方式在主调度队列上运行。 主队列具有最高优先级,通常保留用于更新 UI 以最大化应用响应速度。
我感到困惑的地方是:在调度队列闭包内更新 UI 元素与仅在同一位置在闭包外编写代码有什么区别? 执行视图主体中的代码确实加载方法比将其发送到调度队列更快吗? 如果不是,为什么?
代码示例:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
}
相对:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
updateUI()
}
}
}
哪个会更快地更新 UI?
DispatchQueue.main.async
的主要用途是当您在后台队列上运行代码并且需要在主队列上执行特定代码块时。
在您的代码中, viewDidLoad
已经在主队列上运行,因此几乎没有理由使用DispatchQueue.main.async
。
但使用它不一定是错误的。 但它确实改变了执行顺序。
没有的示例:
class MyViewController: UIViewController {
func updateUI() {
print("update")
}
override func viewDidLoad() {
super.viewDidLoad()
print("before")
updateUI()
print("after")
}
}
正如人们所料,输出将是:
前
更新
后
现在添加DispatchQueue.main.async
:
class MyViewController: UIViewController {
func updateUI() {
print("update")
}
override func viewDidLoad() {
super.viewDidLoad()
print("before")
DispatchQueue.main.async {
updateUI()
}
print("after")
}
}
并且输出改变:
前
后
更新
这是因为异步闭包在当前 runloop 完成后排队等待运行。
我刚刚遇到了您的问题中描述的确切情况: viewDidLoad()
调用DispatchQueue.main.async
。
就我而言,我想在显示视图之前修改 Storyboard 默认值。
但是当我运行该应用程序时,会立即显示默认的 Storyboard 项目。 动画转场将完成。 只有 THEN 才会通过viewDidLoad()
的代码修改 UI 组件。 因此,在编辑实际值之前,所有默认故事板值都会出现令人讨厌的闪光。
这是因为我通过一个总是首先分派到主线程的辅助函数来修改这些控件。 在第一次显示之前修改控件为时已晚。
所以:在viewDidLoad()
修改 Storyboard UI,而不分派到主线程。 如果您已经在主线程上,请在那里完成工作。 否则您最终的异步调度可能为时已晚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.