此应用程序正在从后台线程修改自动布局引擎,这可能会导致引擎损坏和怪异的崩溃
当我在模拟器中运行我的应用程序时,我在控制台中得到这个日志。 在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];
- UIAlertController:supportedInterfaceOrientations被recursion地调用
- 如果NSAllowsArbitraryLoads设置为YES,App Store是否拒绝提交?
- 如何在iOS 9中使用新旧金山字体?
- OSStatus错误代码-34018
- Xcode 7 iOS 9 UITableViewCell分隔符插入问题
- iOS9:通用链接不起作用
- 是否有可能select你的iPad应用程序在iOS 9上的多任务处理
- canOpenUrl – 此应用程序不允许查询schemeinstragram
- 尝试加载视图控制器的视图,而它正在释放… UIAlertController