我只在登录过程中遇到此问题。在当前控制器连接外部数据库(添加用户名和密码后)和获取响应应用程序后应解除当前控制器并应打开下一个视图控制器。我正确地得到了服务器响应。
let postString = “lgn=sedr&UNAME=\(userName)&PASSWORD=\(password)"
let request=NSMutableURLRequest(URL: NSURL(string:url)!)
request.HTTPMethod = "POST";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler:{ ( data,response,error) -> Void in
print(NSThread.isMainThread())
if error != nil {
// print("error=\(error)")
return
}
var parsingError: NSError?
if let dictionary = NSJSONSerialization.JSONObjectWithData(data,options: nil,error: &parsingError) as NSDictionary? {
println("dic: \(dictionary)")
if var suc:AnyObject=dictionary["success"] {
println("success: \(suc)")
if((suc as AnyObject! as Int)==1) {
if let userID = dictionary["userId"] {
println("userid: \(userID)")
//Save data
NSUserDefaults.standardUserDefaults().setObject("true",forKey:"isLogged");
NSUserDefaults.standardUserDefaults().setObject(userID,forKey:"userID");
NSUserDefaults.standardUserDefaults().synchronize();
var storyboard: UIStoryboard = UIStoryboard (name: "Main", bundle: nil)
var vc: UIViewController = storyboard.instantiateViewControllerWithIdentifier("BControllerID") as UIViewController
self.presentViewController(vc ,animated: true, completion: nil )
} else {
self.displayErrorAlert("Oops! Error");
}
}
}
}
});
task.resume();
这是我收到的错误日志:
2016-12-12 14:14:42.911 appService[39180:1705287] *** Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit_Sim/UIKit-3318.93/Keyboard/UIKeyboardTaskQueue.m:374
2016-12-12 14:14:42.917 appService[39180:1705287] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
我有更多的控制器做类似的过程,但我只得到这个控制器的这个例外。
从互联网上发现,由于没有相关的断言而没有使用主线程进行UI更新,因此发生此错误。我检查了所有组件,所有组件都存在。我认为这是因为没有使用主线程。但我不知道如何解决它。
答案 0 :(得分:13)
您需要在主线程上调用新控制器,而不是在后台线程上调用。当前,您在不在主线程上呈现视图的块。使用像这样呈现视图控制器的调度队列:
dispatch_async(dispatch_get_main_queue(), {
var storyboard: UIStoryboard = UIStoryboard (name: "Main", bundle: nil)
var vc: UIViewController = storyboard.instantiateViewControllerWithIdentifier("BControllerID") as UIViewController
self.presentViewController(vc ,animated: true, completion: nil )
}
或像swift 3这样:
DispatchQueue.main.async {
//your block of code
}