2015-06-20 18 views
8

In questo codice di seguito chiamo la funzione displayMyAlertMessage() due volte. il primo che sto chiamando funziona perfettamente, ma il secondo mi dà un errore dicendo che la funzione può essere chiamata solo dal thread principale. Come posso farlo nella mia situazione?La funzione può essere richiamata solo nel thread principale, perché?

Sto usando questo codice:

@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() 
} 

chiamare questa funzione:

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) 
} 

L'errore che sto ottenendo:

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

è possibile modificare solo l'interfaccia utente dal thread principale e si sta cercando di cambiare da un thread in background. – nhgrif

+0

@nhgrif Qual è il modo giusto per fare ciò che voglio fare? – sdd

risposta

12

Si deve sempre aggiornare elementi dell'interfaccia utente dal coda principale, a volte funziona quando non lo fai, ma il più delle volte hai comportamenti strani nella tua app, sei fortunato che il compilatore sia w vviso voi, a volte prendere giorni di tempo per trovare gli errori del genere quando le cose non funzionano

utilizzare il codice qui sotto per chiamare e respingere le vostre opinioni degli avvisi

dispatch_async(dispatch_get_main_queue()) { 
    self.dismissViewControllerAnimated(true, completion: nil) 
} 

dispatch_async(dispatch_get_main_queue()) { 
    self.displayMyAlertMessage("Wrong name or password") 
} 

Si può vedere più in dettaglio su di esso a Grand Central Dispatch (GCD) Reference

+0

Perfetto, grazie – sdd

+0

@sdd Felice di poterti aiutare, fortunato con la tua app! – Icaro

0

È necessario mettere il processo in coda per farlo eseguire.

È possibile fare riferimento all'esempio seguente come sono riuscito a risolverlo nel mio scenario quando ho riscontrato lo stesso problema.

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 { 
} 
3

È necessario prima ignorare le visualizzazioni di avviso. Usa il codice qui sotto per farlo.

Funziona con Swift 3

DispatchQueue.main.async { 
    your code goes here 
} 
Problemi correlati