我在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()
关闭登录窗口。这会导致错误。
答案 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
})