我有一个测试连接操作逻辑。它将实时或不实时测试服务器。当逻辑完成测试并尝试在闭包线程内显示 UIAlertController 时会发生错误,这会使系统崩溃。
@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] 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 = >-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
在主线程上实例化,但可以在任何线程上执行,因此您需要更改打开警报 Controller 的部分,使其明确位于主线程上:
//previous code as above...
DispatchQueue.main.async {
self.present(alertController, animated: true){
// The alert was present
}
}
如果您不打算使用它,您也可以将警报 Controller 的完成处理程序设置为 nil,而不是空闭包。
关于ios - 显示 UIAlert 会使应用程序崩溃吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58735355/