嵌套DispatchQueue.main.async

时间:2019-03-11 18:41:51

标签: ios swift uialertcontroller

我正在从VC调用的函数中显示警报。我不希望主VC被阻止。我正在异步调用此警报功能。该函数又具有另一个异步。这是好的做法,还是我做错了?

有人可以建议遵循以下代码的良好做法吗?

FileInputStream fis = new FileInputStream("db.properties");

3 个答案:

答案 0 :(得分:3)

显示警报不会阻止线程。 present(_:animated:completion:)不是阻塞操作,因此没有理由添加所有这些.async调用。

也就是说,您不想尝试在viewDidLoad内部显示警报。还为时过早。您的视图控制器尚未显示在屏幕上。您应该将showAlert()放在viewDidAppear中,然后删除所有.async调用。

作为一般规则,在任何情况下,尤其是当视图控制器即将出现在屏幕上时,这类模式警告都应该是最后的手段。通常,您应该将要呈现给用户的任何消息集成到视图本身,而不是阻塞整个UI。但是,如果警报是适当的(有时是警报),那么只要您在主队列中就可以直接显示警报。

答案 1 :(得分:1)

您似乎对DispatchQueue有问题:)

您的程序在运行时使用操作队列。此队列可以是系统定义的(例如main)或用户定义的。使用DispatchQueue.main.async(_:)时,会将代码块排队到主队列中。时间到了,主队列执行它们。

但是在viewDidLoad(_:)中,您已经在main队列中。另外,调用AlertController的原因是UI操作,除main之外,不能在任何队列上执行UI操作,您不需要将代码块发送到任何队列,并且您不应t。

而且,就像@ SeanRobinson159所说的那样,AlertController在屏幕上时不会阻塞主线程。就像您的其他ViewControllers一样。

因此,在哪种情况下,您应该使用DispatchQueue来呼叫AlertController

您应该使用DispatchQueue.main.async(_:)将执行UI操作(如调用AlertController或更改UILabel的文本)的代码块从其他队列发送到主队列。例如,也许您从事网络运营。您可以在不同的线程中进行操作,并且在结果出现时,可以将进行UI操作的代码块发送到主队列。

您可以在GCD(中央中央调度站)上搜索详细信息。

答案 2 :(得分:0)

您应该只将必须放在主线程上。因此,您不应将其包装在viewDidLoad函数的main.async块中。

您应该将其包装在具有不同优先级的DispatchQueue中。

DispatchQueue.global(qos: .userInitiated).async { }