此应用程序正在从后台线程修改自动布局引擎,这可能会导致引擎损坏和怪异的崩溃

当我在模拟器中运行我的应用程序时,我在控制台中得到这个日志。 在iOS 8中没有看到这个。我不太确定这是什么原因。 有没有其他人遇到同样的问题,如果是的话如何解决? 或者有没有人可以提供这方面的帮助?

除了主线程以外,不要更改UI。 虽然它可能在某些操作系统或设备上工作,而不是在其他操作系统上工作,但它肯定会使应用程序不稳定,并且崩溃不可预料。

如果您必须回应可能发生在后台的通知,请确保UIKit调用在主线程上进行

你至less有这2个选项:

asynchronous调度

如果你的观察者可以在任何线程上得到通知,使用GCD (Grand Central Dispatch) 。 您可以从任何线程监听并执行工作,并将UI更改封装在dispatch_async

 dispatch_async(dispatch_get_main_queue()) { // Do UI stuff here } 

何时使用GCD ? 当你不控制谁发送通知。 它可以是操作系统,Cocoapod,embedded式库等等。每次使用GCD都会随时唤醒。 下行:你发现自己重新安排工作。


听主线程

方便的是,您可以使用queue参数指定在注册通知要在哪个线程上通知观察者:

 addObserverForName:@"notification" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note){ // Do UI stuff here } 

什么时候在主线观察 ? 当你在注册和注册。 当你回应通知时,你已经是你需要的地方了。


在主线程上发布通知

 [self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:NO]; 

混合解决scheme不保证观察者只能从所述方法中调用。 它允许更轻的观察者,而成本更低的devise。 在这里只提到这个解决scheme, 你应该避免

Swift 3.0

 DispatchQueue.main.async { } 

您需要移动到App的主线程的所有UI部分更新。

我正在调用一个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 } 

OBJ-C:

 [NSOperationQueue mainQueue] addOperationWithBlock:^{ //Do UI stuff here }]; 

应该尝试使用符号断点检测问题: 在这里输入图像说明

符号:

 [UIView layoutIfNeeded]` 

条件:

 !(BOOL)[NSThread isMainThread] 

然后把你的UI更新代码放在主线程中

 DispatchQueue.main.async {} 

同样的问题发生在我的情况下,我不得不按照以下方式更改代码,然后工作正常。 在ViewDidLoad ,通过使用main thread调用此方法,

 [self performSelectorOnMainThread:@selector(setUpTableRows) withObject:nil waitUntilDone:YES];