[英]Nested DispatchQueue.main.async
我正在从VC调用的函数中显示警报。 我不希望主VC被阻止。 我正在异步调用此警报功能。 该函数又具有另一个异步。 这是好的做法,还是我做错了?
有人可以建议遵循以下代码的良好做法吗?
class MyVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Don't block main thread
DispatchQueue.main.async {
self.showAlert(title: "Title", message: "Message")
}
// Do other stuff ...
}
}
func showAlert(title: String = "", message: String) {
alert = UIAlertController(title: title,message: message, preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(cancelAction)
DispatchQueue.main.async {
UIApplication.shared.keyWindow?.rootViewController!.present(alert, animated: true, completion: nil)
}
}
显示警报不会阻塞线程。 present(_:animated:completion:)
不是阻塞操作,因此没有理由添加任何这些.async
调用。
就是说,您不想尝试在viewDidLoad
内部显示警报。 还为时过早。 您的视图控制器尚未显示在屏幕上。 您应该将showAlert()
放在viewDidAppear
,并删除所有.async
调用。
作为一般规则,在任何情况下,尤其是在视图控制器出现在屏幕上时,此类模式警报都应是最后的手段。 通常,您应该将要呈现给用户的任何消息集成到视图本身,而不是阻塞整个UI。 但是,如果警报是适当的(有时是警报),那么只要在主队列中就可以直接显示警报。
看来您有DispatchQueue
问题:)
您的程序在运行时使用操作队列。 该队列可以是系统定义的(例如main
)或用户定义的。 使用DispatchQueue.main.async(_:)
,会将代码块排队到主队列中。 时间到了,主队列执行它们。
但是在viewDidLoad(_:)
,您已经在main
队列中。 另外,调用AlertController
是UI操作,除了main
之外,不能在任何队列上执行UI操作,您不需要将代码块发送到任何队列,也不需要。
而且,就像@ SeanRobinson159所说的那样, AlertController
在屏幕上时不会阻止主线程。 它的工作方式与您的ViewControllers
。
因此,在哪些情况下应使用DispatchQueue
调用AlertController
您应该使用DispatchQueue.main.async(_:)
将执行UI操作(如调用AlertController
或更改UILabel
的文本)的代码块从其他队列发送到主队列。 例如,也许您从事网络运营。 您在不同的线程中进行操作,并且在结果出现时,可以将进行UI操作的代码块发送到主队列。
您可以通过Google GCD(中央调度)获取详细信息。
您应该只把你有什么对主线程。 因此,您不应将其包装在viewDidLoad函数的main.async块中。
您应该将它包装在具有不同优先级的DispatchQueue
。
即DispatchQueue.global(qos: .userInitiated).async { }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.