使用swift在我的OS X中经常遇到此错误:
“此应用程序正在从后台线程修改自动布局引擎,这可能导致引擎损坏和奇怪的崩溃。这将在以后的版本中引发异常。”
我有一个NSWindow,并且正在交换视图到contentView
窗口的视图。尝试在窗口上执行操作或在窗口上添加操作时,都会收到错误消息。试图禁用自动调整大小的东西,并且我没有使用自动布局的东西。有什么想法吗?NSApp.beginSheet
subview
有时候很好,什么也没发生,其他时候却完全破坏了我UI
,没有负载
使用swift在我的OS X中经常遇到此错误:
“此应用程序正在从后台线程修改自动布局引擎,这可能导致引擎损坏和奇怪的崩溃。这将在以后的版本中引发异常。”
我有一个NSWindow,并且正在交换视图到contentView
窗口的视图。尝试在窗口上执行操作或在窗口上添加操作时,都会收到错误消息。试图禁用自动调整大小的东西,并且我没有使用自动布局的东西。有什么想法吗?NSApp.beginSheet
subview
有时候很好,什么也没发生,其他时候却完全破坏了我UI
,没有负载
Answers:
需要将其放置在不同的线程中,以便在线程功能执行完成后立即更新UI:
现代雨燕:
DispatchQueue.main.async {
// Update UI
}
较早版本的Swift,低于Swift 3。
dispatch_async(dispatch_get_main_queue(){
// code here
})
目标C:
dispatch_async(dispatch_get_main_queue(), ^{
// code here
});
在不使用'dispatch_async'的情况下使用打印语句进行调试时,您会收到类似的错误消息,因此当您收到该错误消息时,它的使用时间
斯威夫特4
DispatchQueue.main.async { //code }
迅捷3
DispatchQueue.main.async(){ //code }
早期的Swift版本
dispatch_async(dispatch_get_main_queue()){ //code }
dispatch_async(dispatch_get_main_queue(), ^{ /* UI related code */ });
编辑:我更新了他的答案,语法格式在那里效果更好。
实际问题发生很长时间之后,在控制台中记录了“此应用程序正在从后台线程修改自动布局引擎”错误,因此在不使用断点的情况下很难调试。
我使用@markussvensson的答案来检测我的问题,并使用以下符号断点(调试>断点>创建符号断点)找到了问题:
[UIView layoutIfNeeded]
或[UIView updateConstraintsIfNeeded]
!(BOOL)[NSThread isMainThread]
在模拟器上构建并运行该应用程序,并复制导致引发错误消息的步骤(该应用程序将比平时慢!)。然后,Xcode将停止应用程序,并标记从后台线程访问UI的代码行(例如,函数的调用)。
movq 0x10880ba(%rip), %rsi ; "_wantsReapplicationOfAutoLayoutWithLayoutDirtyOnEntry:"
当您尝试更新文本字段值或在后台线程内添加子视图时,您可能会遇到此问题。因此,您应将此类代码放入主线程中。
您需要使用dispatch_asynch包装调用UI更新的方法以获取主队列。例如:
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.friendLabel.text = "You are following \(friendCount) accounts"
})
现在,我们可以按照以下代码进行操作:
// Move to a background thread to do some long running work
DispatchQueue.global(qos: .userInitiated).async {
// Do long running task here
// Bounce back to the main thread to update the UI
DispatchQueue.main.async {
self.friendLabel.text = "You are following \(friendCount) accounts"
}
}
对我而言,此错误消息源自Admob SDK的横幅。
通过设置条件断点,我能够将原点跟踪到“ WebThread”。
然后,我可以通过将Banner创建封装为以下内容来解决此问题:
dispatch_async(dispatch_get_main_queue(), ^{
_bannerForTableFooter = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];
...
}
我不知道为什么这样做有帮助,因为我看不到如何从非主线程调用此代码。
希望它可以帮助任何人。
由于我使用,出现了同样的问题performSelectorInBackground
。
您不得在主线程之外更改UI!UIKit并不是线程安全的,因此如果您这样做,将会出现上述问题以及其他一些奇怪的问题。该应用程序甚至可能崩溃。
因此,要执行UIKit操作,您需要定义块并让其在主队列上执行:例如,
NSOperationQueue.mainQueue().addOperationWithBlock {
}
显然,您正在对后台线程进行一些UI更新。无法准确预测位置,而看不到您的代码。
以下是一些可能发生的情况:
您可能正在后台线程上做某事而不使用。由于具有相同的功能,因此该代码更容易发现。
DispatchQueue.main.async { // do UI update here }
在后台线程上调用一个执行Web请求的func调用,其完成处理程序在执行ui更新时调用另一个func。要解决此问题,请尝试在webrequest调用之后检查已更新UI的代码。
// Do something on background thread
DispatchQueue.global(qos: .userInitiated).async {
// update UI on main thread
DispatchQueue.main.async {
// Updating whole table view
self.myTableview.reloadData()
}
}
“此应用程序正在从后台线程修改自动布局引擎”的主要问题是,似乎在实际问题发生后很长时间才被记录下来,这会使故障排除非常困难。
通过创建三个符号断点,我设法解决了这个问题。
调试>断点>创建符号断点...
断点1:
符号: -[UIView setNeedsLayout]
健康)状况: !(BOOL)[NSThread isMainThread]
断点2:
符号: -[UIView layoutIfNeeded]
健康)状况: !(BOOL)[NSThread isMainThread]
断点3:
符号: -[UIView updateConstraintsIfNeeded]
健康)状况: !(BOOL)[NSThread isMainThread]
有了这些断点,您就可以轻松地在错误地调用非主线程上的UI方法的实际行上中断。
设置文本字段/标签值或在后台线程内添加子视图可能很简单,这可能会导致字段布局发生变化。确保对接口所做的任何操作仅在主线程中发生。
斯威夫特4
假设,如果您正在使用操作队列调用某些方法
operationQueue.addOperation({
self.searchFavourites()
})
假设函数searchFavourites就像,
func searchFavourites() {
DispatchQueue.main.async {
//Your code
}
}
如果调用主线程上方法“ searchFavourites”内的所有代码,则在其中更新某些UI时仍会给出错误。
从主线程访问引擎后,此应用程序正在从后台线程修改自动布局引擎。
所以用溶液
operationQueue.addOperation({
DispatchQueue.main.async {
self.searchFavourites()
}
})
对于这种情况。
在这里从日志中查看这一行
$S12AppName18ViewControllerC11Func()ySS_S2StF + 4420
您可以检查是从后台线程中调用哪个函数,还是从哪里调用api方法,您需要像这样从主线程中调用函数。
DispatchQueue.main.async { func()}
func()是要在api调用成功或其他情况下调用的函数。
在这里记录
This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
Stack:(
0 Foundation 0x00000001c570ce50 <redacted> + 96
1 Foundation 0x00000001c5501868 <redacted> + 32
2 Foundation 0x00000001c5544370 <redacted> + 540
3 Foundation 0x00000001c5543840 <redacted> + 396
4 Foundation 0x00000001c554358c <redacted> + 272
5 Foundation 0x00000001c5542e10 <redacted> + 264
6 UIKitCore 0x00000001f20d62e4 <redacted> + 488
7 UIKitCore 0x00000001f20d67b0 <redacted> + 36
8 UIKitCore 0x00000001f20d6eb0 <redacted> + 84
9 Foundation 0x00000001c571d124 <redacted> + 76
10 Foundation 0x00000001c54ff30c <redacted> + 108
11 Foundation 0x00000001c54fe304 <redacted> + 328
12 UIKitCore 0x00000001f151dc0c <redacted> + 156
13 UIKitCore 0x00000001f151e0c0 <redacted> + 152
14 UIKitCore 0x00000001f1514834 <redacted> + 868
15 UIKitCore 0x00000001f1518760 <redacted> + 104
16 UIKitCore 0x00000001f1543370 <redacted> + 1772
17 UIKitCore 0x00000001f1546598 <redacted> + 120
18 UIKitCore 0x00000001f14fc850 <redacted> + 1452
19 UIKitCore 0x00000001f168f318 <redacted> + 196
20 UIKitCore 0x00000001f168d330 <redacted> + 144
21 AppName 0x0000000100b8ed00 $S12AppName18ViewControllerC11Func()ySS_S2StF + 4420
22 AppName 0x0000000100b8d9f4 $S12CcfU0_y10Foundation4DataVSg_So13NSURLResponseCSgs5Error_pSgtcfU_ + 2384
23 App NAme 0x0000000100a98f3c $S10Foundation4DataVSgSo13NSURLResponseCSgs5Error_pSgIegggg_So6NSDataCSgAGSo7NSErrorCSgIeyByyy_TR + 316
24 CFNetwork 0x00000001c513aa00 <redacted> + 32
25 CFNetwork 0x00000001c514f1a0 <redacted> + 176
26 Foundation 0x00000001c55ed8bc <redacted> + 16
27 Foundation 0x00000001c54f5ab8 <redacted> + 72
28 Foundation 0x00000001c54f4f8c <redacted> + 740
29 Foundation 0x00000001c55ef790 <redacted> + 272
30 libdispatch.dylib 0x000000010286f824 _dispatch_call_block_and_release + 24
31 libdispatch.dylib 0x0000000102870dc8 _dispatch_client_callout + 16
32 libdispatch.dylib 0x00000001028741c4 _dispatch_continuation_pop + 528
33 libdispatch.dylib 0x0000000102873604 _dispatch_async_redirect_invoke + 632
34 libdispatch.dylib 0x00000001028821dc _dispatch_root_queue_drain + 376
35 libdispatch.dylib 0x0000000102882bc8 _dispatch_worker_thread2 + 156
36 libsystem_pthread.dylib 0x00000001c477917c _pthread_wqthread + 472
37 libsystem_pthread.dylib 0x00000001c477bcec start_wqthread + 4
)