[英]The application is modifying the Autolayout Engine from background thread
[英]This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes
我在模擬器中運行應用程序時,會在控制台中收到此日志。 在iOS 8中還沒有看到這個。我不太確定是什么原因造成的。 還有其他人遇到過同樣的問題嗎?如果可以,如何解決? 或有任何人可以為此提供幫助嗎?
除了主線程外,請勿從其他任何內容更改UI。 盡管它似乎可以在某些OS或設備上運行,而不是在其他操作系統或設備上運行,但勢必會使您的應用程序不穩定,並且無法正常崩潰。
如果您必須響應可能在后台發生的通知,則請確保UIKit
調用發生在主線程上 。
您至少有以下兩個選擇:
如果可以在任何線程上通知您的觀察者,請使用GCD
(大中央調度) 。 您可以從任何線程偵聽和執行工作,並將UI更改封裝在dispatch_async
:
dispatch_async(dispatch_get_main_queue()) {
// Do UI stuff here
}
什么時候使用GCD
? 當您不控制誰發送通知時。 它可以是操作系統,Cocoapod,嵌入式庫等。使用GCD
隨時隨地都會醒來。 缺點:您發現自己重新安排了工作。
方便地,您可以使用queue
參數指定在注冊通知時要在哪個線程上通知觀察者:
addObserverForName:@"notification"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
// Do UI stuff here
}
什么時候在主線程上觀察 ? 當您同時注冊和注冊時。 在您回復通知之時,您已經處在需要的位置。
[self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:NO];
不能保證僅從所述方法調用觀察者的混合解決方案。 它允許更輕的觀察者,但代價是不那么堅固。 在這里僅提及您可能應該避免的解決方案。
斯威夫特3.0
DispatchQueue.main.async {
}
您需要將所有UI部分更新移至App的MAIN線程中。
我在后台調用createMenuView()時遇到錯誤
“此應用程序正在從后台線程修改自動布局引擎,這可能導致引擎損壞和怪異的崩潰”
所以我在主線程中使用了上面的方法
DispatchQueue.main.async {
}
在SWIFT 3.0和Xcode 8.0中
正確的代碼如下:
RequestAPI.post(postString: postString, url: "https://www.someurl.com") { (succeeded: Bool, msg: String, responceData:AnyObject) -> () in
if(succeeded) {
print(items: "User logged in. Registration is done.")
// Move to the UI thread
DispatchQueue.main.async (execute: { () -> Void in
//Set User's logged in
Util.set_IsUserLoggedIn(state: true)
Util.set_UserData(userData: responceData)
self.appDelegate.createMenuView()
})
}
else {
// Move to the UI thread
DispatchQueue.main.async (execute: { () -> Void in
let alertcontroller = UIAlertController(title: JJS_MESSAGE, message: msg, preferredStyle: UIAlertControllerStyle.alert)
alertcontroller.title = "No Internet"
alertcontroller.message = FAILURE_MESSAGE
self.present(alertcontroller, animated: true, completion: nil)
})
}
}
您具有從后台線程更新UI布局的代碼。 無需明確更改運行代碼的操作隊列。 例如,NSURLSession.shared()在發出新請求時不使用主隊列。 為了確保您的代碼在主線程上運行,我使用了NSOperationQueue的靜態方法mainQueue()。
迅速:
NSOperationQueue.mainQueue().addOperationWithBlock(){
//Do UI stuff here
}
對象:
[NSOperationQueue mainQueue] addOperationWithBlock:^{
//Do UI stuff here
}];
我的情況也一樣,我必須按照以下方式更改代碼,然后才能正常工作。 在ViewDidLoad
,使用main thread
調用此方法,
[self performSelectorOnMainThread:@selector(setUpTableRows) withObject:nil waitUntilDone:YES];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.