在下面的代码中,我调用函数displayMyAlertMessage()两次。我调用的第一个工作完美,但第二个给我一个错误,说该函数只能从主线程调用。我怎么能在我的情况下这样做?
我正在使用此代码:
@IBAction func loginButtonTapped(sender: AnyObject) {
result2Value = ""
let userEmail = userEmailTextField.text
let userPassword = userPasswordTextField.text
if userPassword.isEmpty || userPassword.isEmpty {
displayMyAlertMessage("All fields are required")
return;
}
//send user data to server side
let myUrl = NSURL(string: "http://www.avanta.com/extra/test-userLogin.php")
let request = NSMutableURLRequest(URL:myUrl!)
request.HTTPMethod = "POST"
let postString = "email=\(userEmail)&password=\(userPassword)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if error != nil{
println("error\(error)")
return
}
var err:NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary
if let parseJSON = json {
var resultValue:String = parseJSON["status"] as! String!
println("result: \(resultValue)")
if (resultValue == "Success") {
//login succesful
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isUserLogin")
NSUserDefaults.standardUserDefaults().synchronize()
self.dismissViewControllerAnimated(true, completion: nil)
// return
}
else{
self.displayMyAlertMessage("Wrong name or password")
}
}
}
task.resume()
}
要调用此功能:
func displayMyAlertMessage(userMessage:String){
var myAlert = UIAlertController(title:"Alert", message:userMessage, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title:"Ok", style:UIAlertActionStyle.Default, handler:nil)
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated:true, completion:nil)
}
我得到的错误:
2015-06-20 14:44:41.646 UserLoginAndRegistration[6064:750474] *** Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit/UIKit-3318.16.14/Keyboard/UIKeyboardTaskQueue.m:374
2015-06-20 14:44:41.657 UserLoginAndRegistration[6064:750474] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '- [UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
*** First throw call stack:
(0x186551e48 0x196c4c0e4 0x186551d08 0x1873d5554 0x18ad2b0a8 0x18ad2b734 0x18ad24a1c 0x18b251564 0x18b0156a8 0x18b0169e4 0x18b0188dc 0x18adee0b4 0x100028f9c 0x10002b500 0x10002b5f4 0x10002b624 0x10002b68c 0x185ee6540 0x187407508 0x187358c94 0x18734861c 0x18740a26c 0x1005a4df0 0x1005af854 0x1005a8120 0x1005b175c 0x1005b2f18 0x19746d2e4 0x19746cfa8)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
答案 0 :(得分:12)
您必须始终更新主要队列中的UI元素,有时候在您不熟悉的情况下有效,但大多数时候您的应用程序中都有奇怪的行为,运气好,编译器会警告您,有时需要几天时间才能发现错误就像那些事情不起作用一样
使用以下代码来调用和关闭您的提醒视图
dispatch_async(dispatch_get_main_queue()) {
self.dismissViewControllerAnimated(true, completion: nil)
}
dispatch_async(dispatch_get_main_queue()) {
self.displayMyAlertMessage("Wrong name or password")
}
看到有关它的更多详细信息
答案 1 :(得分:3)
您需要先解除警报视图。请使用以下代码执行此操作。
适用于Swift 3
DispatchQueue.main.async {
your code goes here
}
答案 2 :(得分:0)
您应该将您的进程放入队列以使其执行。
您可以参考下面的示例,当我遇到同样的问题时,我是如何在我的方案中解决它的。
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)
//Above line was generating same exception in my scenario
// I got it resolved by using NSOperationQueue.mainQueue().addOperationWithBlock {
}