2013-01-15 12 views
16

dismissViewControllerAnimated: completamento: funziona correttamente nella mia applicazione, ad eccezione del ritardo tra il licenziamento.dismissViewControllerAnimated: completamento: ha un secondo ritardo di ritardo

[api loginWithUsername:[dict objectForKey:@"username"] andPassword:[dict objectForKey:@"password"] andSuccessBlock:^(id json) { 
    NSLog(@"DONE... %@", [json objectForKey:@"status"]); 
    NSString *status = [json objectForKey:@"status"]; 
    if([status isEqualToString:@"ok"]){ 
     app.user = [json objectForKey:@"data"]; 
     [self dismissViewControllerAnimated:YES completion:nil]; 
    }else{ 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"could not log you in" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
     [alert show]; 
    } 
}]; 

Nella mia console vedo echo'ed "DONE ... ok", che significa il blocco di richiamata è stata eseguita, tuttavia circa 3-4 secondi dopo la vista modale è finalmente respinto.

Che cosa potrebbe causare questo ritardo?

+0

Utilizza il profiler Time di Instrument per vedere cosa richiede più tempo – Mario

risposta

33

Se non si garantisce che il codice UI sia in esecuzione su Main Thread, potrebbe funzionare su alcuni altri e in tal caso, si verificheranno alcuni secondi di ritardo!

È possibile aggiungere questo per fare in modo che il licenziamento sia riceve un thread principale:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self dismissViewControllerAnimated:YES completion:nil]; 
}); 

In generale, questo non è un problema in quanto la maggior parte del codice sarà già in esecuzione sul thread principale, dal momento che la maggior parte aggiungiamo codice eseguito da metodi UIKit, come viewDidLoad e così via. Questi metodi sono garantiti per essere eseguiti sul thread principale.

Il problema si verifica quando si termina l'esecuzione del codice su un altro thread. Un caso in cui ciò può accadere è ad esempio su una chiamata di blocco di completamento di una libreria di rete, in cui la richiesta viene eseguita in background.

+2

questo era esattamente il problema. – Chadams

+0

Posso sapere perché ho bisogno di questo? Ho un semplice PresentedViewcontroller. Ad un certo punto eseguo [self dismissViewControllerAnimated: YES completion:^{ [self.delegate funcDidSelected]; }]; e quando cancello il ViewController presentato ci vogliono 5 secondi per eseguirlo. Il mio presentatoreViewController non fa cose complesse invece di avere un semplice UITableView. – felixwcf

+1

@Felix perché chiudere e presentare i controller di visualizzazione è un'azione dell'interfaccia utente. Tutte le azioni dell'interfaccia utente devono essere eseguite sul thread principale dell'applicazione. Il comportamento di te che esegui tali azioni su qualsiasi altro thread, di solito è un grande ritardo, o anche loro non hanno alcun effetto. La maggior parte del tuo codice gira già sul thread principale, quindi di solito non devi preoccuparti di questo, ma in alcuni casi lo fai. – manecosta

3

Controllare 'viewWillAppear' di ParentViewController e 'viewWillDisappear' del controllore currentView. Assicurarsi che queste due funzioni non contengano calcoli pesanti e allocazioni di memoria all'interno.

+0

Questa è la risposta corretta nel mio caso! – Jack

0

Provare a cambiare

NSString *status = [json objectForKey:@"status"]; 
NSLog(@"DONE... %@", status); 

e quindi provare

if ([Stato isEqualToString: @ "ok"]) {

[self dismissViewControllerAnimated:YES completion:nil]; 
    app.user = [json objectForKey:@"data"]; 
}else{ 

Come ho non so quanto è grande il tuo JSON l'oggetto è che potrebbe prendersi un momento per rispondere e come lo si sta chiamando di nuovo dopo la dichiarazione di registro e il fare qualcos'altro prima di dire che può essere respinto.