线程+多个窗口导致奇怪的错误

时间:2015-11-12 05:08:17

标签: multithreading swift macos

我在swift中有两个窗口,一个像登录对话框,它将NSURLConnection.sendAsynchronousRequest发送到服务器以进行身份​​验证。一旦得到响应,窗口应该关闭。

当我关闭Window时(从登录窗口类或主窗口clasS)我得到这些错误:

This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes. This will cause an exception in a future release.

我已经尝试了所有方式的后台线程等。但我认为问题是我正在关闭窗口为什么asynch NSURLConnection请求仍然挂起。

我从登录窗口发送异步请求的代码:

dispatch_async(dispatch_get_main_queue(), {
            let queue:NSOperationQueue = NSOperationQueue()
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
                var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
                let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
                let result: NSString = NSString(data: data, encoding: NSUTF8StringEncoding)!

                let expectedString = "special auth string"!
                if(result == expectedString) {
                    self.callback.loginOK()
                } else {
                    self.output.stringValue = result
                }
                return
            })
        })

该类的回调成员是生成它的父视图控制器,然后我从主应用程序窗口使用loginVC.view.window?.close()关闭登录窗口。这会导致错误。

1 个答案:

答案 0 :(得分:1)

问题是NSURLConnection.sendAsynchronousRequest将始终在辅助线程中运行,因此尽管从主线程显式调用它,但它将从该辅助线程调用其回调。 您不需要在主线程中包装NSURLConnection.sendAsynchronousRequest,而是使用dispatch_async将'self.callback.loginOK()'包装在主线程中运行,以确保在辅助线程中不会发生与UI相关的操作。像这样的东西 -

let queue:NSOperationQueue = NSOperationQueue()
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
                var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
                let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
                let result: NSString = NSString(data: data, encoding: NSUTF8StringEncoding)!

               dispatch_async(dispatch_get_main_queue() {
                let expectedString = "special auth string"!
                if(result == expectedString) {
                    self.callback.loginOK()
                } else {
                    self.output.stringValue = result
                }
              })

                return
            })