DispatchQueue:不可在非主线程上使用asCopy = NO进行调用。

45

我将UIAlertController在主线程上呈现,如下:

class HelperMethodClass: NSObject {

    class func showAlertMessage(message:String, viewController: UIViewController) {
        let alertMessage = UIAlertController(title: "", message: message, preferredStyle: .alert)

        let cancelAction = UIAlertAction(title: "Ok", style: .cancel)

        alertMessage.addAction(cancelAction)

        DispatchQueue.main.async {
            viewController.present(alertMessage, animated: true, completion: nil)
        }
    }
}

我可以在任何UIViewController中调用此方法:

HelperMethodClass.showAlertMessage(message: "Any Message", viewController: self)

我能正确地获取输出。

但是,在控制台中我收到以下消息:

[断言] 不能在非主线程上使用asCopy = NO调用。

这里有什么我做错了吗,或者我可以忽略这条消息吗?

编辑

感谢@NicolasMiari :

添加下面的代码不会显示任何消息:

DispatchQueue.main.async {
    HelperMethodClass.showAlertMessage(message: "Any Message", viewController: self)
}

之前为什么会在控制台显示该消息的原因是什么?


3
你尝试将从 let alertMessage =... 开始的 所有内容 移动到 async 块内吗? - Nicolas Miari
另外:您尝试设置断点并逐步执行,以查看哪一行触发了警告吗?当在调用堆栈上看到showAlertMessage()方法时,该线程运行在哪里? - Nicolas Miari
1个回答

85

您应该在主队列上调用showAlertMessage中的所有代码:

class func showAlertMessage(message:String, viewController: UIViewController) {
    DispatchQueue.main.async {
        let alertMessage = UIAlertController(title: "", message: message, preferredStyle: .alert)

        let cancelAction = UIAlertAction(title: "Ok", style: .cancel)

        alertMessage.addAction(cancelAction)

        viewController.present(alertMessage, animated: true, completion: nil)
    }
}

4
为什么需要这个? - nonolays
4
@Jeff 这个视频没有回答这个问题。我也想知道为什么我们需要在主线程上实例化UIAlertController。 - Vin Gazoil
2
@VinGazoil 任何时候更新UI都需要在主线程上进行。我不能确定为什么UIAlertController不在主线程上,但是print(Thread.isMainThread)会告诉你是否在主线程上。 - Jeff
5
我仍然不太清楚为什么创建UIAlertController需要在主线程中进行...如果没有这个,我们会遇到非常奇怪的行为(人们无法点击屏幕上的随机部分)。 - monstermac77
2
我知道这很奇怪,但任何视图控制器都应该在主线程上实例化,而不仅仅是在呈现时。在呈现之前的任何时候,视图控制器都可能加载其视图甚至修改它们,以响应某些公共方法的使用。 - androidguy
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接