我在swift中有两个窗口,其中一个就像登录对话框,它将NSURLConnection.sendAsynchronousRequest
发送到服务器以进行身份验证。一旦它得到响应,窗口就应该关闭。
当我关闭窗口(从登录窗口类或主窗口类)时,我会收到以下错误:
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.
我已经尝试了各种后台线程等。但我认为问题是我正在关闭异步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()
关闭登录窗口。这导致了错误。
问题是NSURLConnection.sendAsynchronousRequest将始终在辅助线程中运行,因此,尽管您从主线程显式调用它,但它的回调仍将从该辅助线程调用。您不需要在主线程中包装NSURLConnectionsendAsynchronousRequest,而是使用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
})