显示 UIAlert 会使应用程序崩溃吗? [英] display UIAlert will crash the app on present?

查看:83
本文介绍了显示 UIAlert 会使应用程序崩溃吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个测试连接操作逻辑.它将实时测试服务器.当逻辑完成测试并尝试在闭包线程中显示 UIAlertController 时会发生该错误,这会使系统崩溃.

I have a test connection action logic. it will test the server in live or not. the bug happens when the logic finishes the test and try display UIAlertController inside closure thread it will crash the systems.

@IBAction func TestNetwork(_ sender: Any) {
    var message = "\(internetConnection) internet connection \n \(serverStatus) server\n  "
    self.showSpinner(onView: self.view)
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
        self.testConnection(connectionTestCompletionHanlder: {connectionResult in


            let alertController = UIAlertController(title: "Alert", message: message, preferredStyle: .alert)
            let defaultAction = UIAlertAction(title: "OK", style: .default) { (action) in
                // Respond to user selection of the action.
            }
            alertController.addAction(defaultAction)
            //self.removeSpinner()
            self.present(alertController, animated: true){
                // The alert was presented
            }
        })
    }
}

错误

-[Assert] 不能在非主线程上使用 asCopy = NO 调用.+[UIView setAnimationsEnabled:] 从后台线程调用.从 UIView 或一个后台线程执行任何操作不支持子类,可能会导致意外和阴险行为.
- 不支持在主线程之外使用 UIKit 视图自定义 API.-setHasDimmingView: 发送到 <_UIAlertControllerView: 0x7ffe2ff8b4a0;框架 = (0 0; 375 667);层 = >

-[Assert] Cannot be called with asCopy = NO on non-main thread. +[UIView setAnimationsEnabled:] being called from a background thread. Performing any operation from a background thread on UIView or a subclass is not supported and may result in unexpected and insidious behavior.
-Unsupported use of UIKit view-customization API off the main thread. -setHasDimmingView: sent to <_UIAlertControllerView: 0x7ffe2ff8b4a0; frame = (0 0; 375 667); layer = >

-由于未捕获的异常NSInternalInconsistencyException"而终止应用程序,原因:修改布局引擎不能在它之后从后台线程执行已从主线程访问.'

-Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.'

推荐答案

根据上面的评论,您应该始终在主线程上启动 UI 工作.上面的完成处理程序虽然通过 asyncAfter 在主线程上实例化,但可以在任何线程上执行,因此您需要将打开警报控制器的部分更改为显式位于主线程上:

As per the comments above, you should always launch UI work on the main thread. The completion handler you have above, although instantiated on the main thread through the asyncAfter could execute on any thread, so you therefore need to change the section that opens the alert controller to explicitly be on the main thread:

//previous code as above...

DispatchQueue.main.async {
  self.present(alertController, animated: true){
    // The alert was present
  }
}

如果您不打算使用它,您也可以将警报控制器的完成处理程序设置为 nil,而不是使用一个空的闭包.

You could also set the alert controller's completion handler to nil if your are not planning to utilise it, rather than having an empty closure.

这篇关于显示 UIAlert 会使应用程序崩溃吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆