此应用程序正在从后台线程修改autolayout引擎,这可能导致引擎损坏和奇怪的崩溃

Sha*_*bba 36 iphone ios9 xcode7-beta4

当我在模拟器中运行我的应用程序时,我在控制台中获取此日志.在iOS 8中没有看到这个.我不太清楚是什么导致了这一点.有没有其他人遇到同样的问题,如果是这样,它是如何解决的?或者是否有人可以提供任何帮助?

Swi*_*ect 68

除了主线程之外,不要更改UI.虽然它似乎可以在某些操作系统或设备上运行而不是其他操作系统,但它必然会使您的应用程序不稳定,并且无法预测崩溃.

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

你至少有这两个选择:

异步调度

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

dispatch_async(dispatch_get_main_queue()) {
    // Do UI stuff here
}
Run Code Online (Sandbox Code Playgroud)

什么时候用GCD?当您不控制谁发送通知时.它可以是操作系统,Cocoapod,嵌入式库等.GCD随时随地都会使用.缺点:您发现自己正在重新安排工作.


听主线程

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

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

什么时候在主线观察?当您注册和注册时.在您回复通知的时候,您已经到了需要的位置.


在主线程上发布通知

[self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:NO];
Run Code Online (Sandbox Code Playgroud)

混合解决方案,不保证仅从所述方法调用观察者.它允许更轻的观察者,成本更低的设计.这里只提到你应该避免的解决方案.


Edu*_*ros 20

Swift 3.0

DispatchQueue.main.async {
}
Run Code Online (Sandbox Code Playgroud)


Ani*_*pta 5

您需要移动到App的MAIN线程中的所有UI部件更新.

我在后台调用createMenuView(),我得到了以下错误

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

所以我将上面的方法调用到主线程中使用

    DispatchQueue.main.async {
    }
Run Code Online (Sandbox Code Playgroud)

在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)
            })
        }
    }
Run Code Online (Sandbox Code Playgroud)