waitUntilAllTask​​sAreFinished错误Swift

当按下Submitbutton时,我在loginViewController中有这个调用:

let http = HTTPHelper() http.post("http://someUrl.com/Login/userEmail/\(username.text)/Pswd/\(userPass.text)", postCompleted: self.checkLogin) 

而我发送的checkLogin函数只是在执行:

 func checkLogin(succeed: Bool, msg: String){ if (succeed){ self.performSegueWithIdentifier("logInTrue", sender: self) } } 

后台function是HTTPHelper类是:

 func post(url : String, postCompleted : (succeeded: Bool, msg: String) -> ()) { var request = NSMutableURLRequest(URL: NSURL(string: url)!) var session = NSURLSession.sharedSession() request.HTTPMethod = "POST" var err: NSError? self.task = session.dataTaskWithURL(NSURL(string: url)!) {(data, response, error) in var strData = NSString(data: data, encoding: NSUTF8StringEncoding) var err: NSError? var json = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: &err) as? NSDictionary var msg = "No message" // Did the JSONObjectWithData constructor return an error? If so, log the error to the console if(err != nil) { let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding) postCompleted(succeeded: false, msg: "Error") } else { // The JSONObjectWithData constructor didn't return an error. But, we should still // check and make sure that json has a value using optional binding. if let parseJSON = json { // Okay, the parsedJSON is here, let's get the value for 'success' out of it if let success = parseJSON["result"] as? Bool { postCompleted(succeeded: success, msg: "Logged in.") } return } else { // Woa, okay the json object was nil, something went worng. Maybe the server isn't running? let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding) postCompleted(succeeded: false, msg: "Error") } } } self.task!.resume() } 

当checkLogin函数被调用成功时:true它无法执行SegueWithIdentified函数..错误如下所示:

断言失败 – [UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished],/SourceCache/UIKit_Sim/UIKit-3318.16.14/Keyboard/UIKeyboardTaskQueue.m:374 2014-11-15 17:41:29.540 Wavesss [8462:846477] ***终止应用程序,由于未捕获的exception'NSInternalInconsistencyException',原因:' – [UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished]只能从主线程调用'。

请帮助我,虽然我很难find一个解决scheme,这似乎是我无法在视图控制器之间传递,而url任务仍在其他线程上执行。 在此先感谢家伙!

您的checkLogin函数正在另一个线程上调用,所以您需要切换回主线程,然后才能调用self.performSegueWithIdentifier 。 我更喜欢使用NSOperationQueue

 func checkLogin(succeed: Bool, msg: String) { if (succeed) { NSOperationQueue.mainQueue().addOperationWithBlock { self.performSegueWithIdentifier("logInTrue", sender: self) } } } 

随着Xcode 8.0和Swift 3,这已被修改为以下结构:

 OperationQueue.main.addOperation{ <your segue or function call> } 

我也有同样的问题,通过参考上面的答案得到解决。 谢谢@Nate

 var storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) var vc: UINavigationController = storyBoard.instantiateViewControllerWithIdentifier("AppViewController") as! UINavigationController NSOperationQueue.mainQueue().addOperationWithBlock { self.presentViewController(vc, animated: true, completion: nil) } 

我在尝试从asynchronous任务中更改文本框的内容时遇到此问题。

解决scheme是使用DispatchQueue(Xcode 8.0和Swift 3.0):

  DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.textBox.text = "Some Value" }