在我的OS X中使用swift遇到了很多这个错误:
“这个应用程序正在从后台线程修改自动布局引擎,这可能会导致引擎损坏和奇怪的崩溃。这将在未来的版本中导致异常。”
我有一个NSWindow我将视图交换到窗口的contentView。当我尝试执行NSApp时会得到错误。或者当我向窗口添加子视图时。尝试禁用自动调整大小的东西,我没有任何使用自动布局的东西。任何想法吗?
有时它很好,什么都没有发生,其他时候它完全破坏了我的UI,什么都没有加载
在我的OS X中使用swift遇到了很多这个错误:
“这个应用程序正在从后台线程修改自动布局引擎,这可能会导致引擎损坏和奇怪的崩溃。这将在未来的版本中导致异常。”
我有一个NSWindow我将视图交换到窗口的contentView。当我尝试执行NSApp时会得到错误。或者当我向窗口添加子视图时。尝试禁用自动调整大小的东西,我没有任何使用自动布局的东西。任何想法吗?
有时它很好,什么都没有发生,其他时候它完全破坏了我的UI,什么都没有加载
当前回答
You already have the correct code answer from @Mark but, just to share my findings: The issue is that you are requesting a change in the view and assuming that it will happen instantly. In reality, the loading of a view depends on the available resources. If everything loads quickly enough and there are no delays then you don't notice anything. In scenarios, where there is any delay due to the process thread being busy etc, the application runs into a situation where it is supposed to display something even though its not ready yet. Hence, it is advisable to dispatch these requests in a asynchronous queues so, they get executed based on the load.
其他回答
“此应用程序正在从后台线程修改自动布局引擎”错误在实际问题发生后很长时间才会记录在控制台中,因此如果不使用断点,调试这个错误可能会很困难。
我使用@markussvensson的答案来检测我的问题,并使用这个符号断点(调试>断点>创建符号断点)发现它:
符号:[UIView layoutIfNeeded]或[UIView updateConstraintsIfNeeded] 条件:!(BOOL)[NSThread是主线程]
在模拟器上构建和运行应用程序,并复制导致抛出错误消息的步骤(应用程序将比平时慢!)然后Xcode将停止应用程序并标记从后台线程访问UI的代码行(例如func的调用)。
我在UITableView中重新加载数据时遇到了这个问题。简单调度重新加载如下固定的问题为我。
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
它需要放在一个不同的线程中,允许UI在线程函数执行完成后立即更新:
现代迅速:
DispatchQueue.main.async {
// Update UI
}
旧版本的Swift,在Swift 3之前。
dispatch_async(dispatch_get_main_queue(){
// code here
})
objective - c:
dispatch_async(dispatch_get_main_queue(), ^{
// code here
});
“这个应用程序正在从后台线程修改自动布局引擎”的主要问题是,它似乎在实际问题发生后很长一段时间才被记录下来,这可能会使它很难排除故障。
我设法通过创建三个符号断点来解决这个问题。
调试>断点>创建符号断点…
断点1:
符号:-[UIView setNeedsLayout] 条件:!(BOOL)[NSThread是主线程]
断点2:
符号:-[UIView layoutIfNeeded] 条件:!(BOOL)[NSThread是主线程]
断点3:
符号:-[UIView updateConstraintsIfNeeded] 条件:!(BOOL)[NSThread是主线程]
使用这些断点,您可以很容易地在非主线程上错误地调用UI方法的实际行中获得断点。
You already have the correct code answer from @Mark but, just to share my findings: The issue is that you are requesting a change in the view and assuming that it will happen instantly. In reality, the loading of a view depends on the available resources. If everything loads quickly enough and there are no delays then you don't notice anything. In scenarios, where there is any delay due to the process thread being busy etc, the application runs into a situation where it is supposed to display something even though its not ready yet. Hence, it is advisable to dispatch these requests in a asynchronous queues so, they get executed based on the load.