2013-01-15 17 views
16

dismissViewControllerAnimated: zakończenie: działa poprawnie w mojej aplikacji, z wyjątkiem opóźnienia między zwolnieniem.dismissViewControllerAnimated: zakończenie: ma kilka sekund opóźnienia

[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]; 
    } 
}]; 

W moim konsoli widzę echo'ed „GOTOWE ... ok”, czyli blok zwrotna została wykonana, jednak około 3-4 sekund później modalna pogląd ostatecznie odrzucony.

Co może być przyczyną tego opóźnienia?

+0

Użyj profilera czasu instrumentu, aby zobaczyć, co zajmuje najwięcej czasu. – Mario

Odpowiedz

33

Jeśli nie gwarantujesz, że kod interfejsu użytkownika jest uruchomiony na głównym wątku, może działać na innym, w takim przypadku wystąpi kilka sekund opóźnienia!

Możesz dodać to, aby upewnić się, że zwolnienie jest prowadzony na głównym wątku:

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

Generalnie nie jest to problem, ponieważ większość kodu będzie już działa na głównym wątku, ponieważ przeważnie dodać kod uruchamiany z metod UIKit, takich jak viewDidLoad i inne. Te metody są gwarantowane w głównym wątku.

Problem pojawia się, gdy kończy się uruchamianie kodu w innym wątku. Jednym z przypadków, w którym może się to zdarzyć, jest na przykład wywołanie bloku biblioteki sieciowej, gdzie żądanie jest wykonywane w tle.

+2

to był dokładnie problem. – Chadams

+0

Czy mogę wiedzieć, dlaczego tego potrzebuję? Mam prosty PresentedViewcontroller. W pewnym momencie wykonuję [self dismissViewControllerAnimated: TAK ukończenie:^{ [self.delegate funcDidSelected]; }]; i kiedy odrzucam presentViewController, wykonanie tego zajmuje 5 sekund. Mój prezentViewController nie robi skomplikowane rzeczy zamiast posiadania prostego UITableView. – felixwcf

+1

@Felix, ponieważ zamykanie i prezentowanie kontrolerów widoku jest działaniem interfejsu użytkownika. Wszystkie działania interfejsu użytkownika muszą być uruchamiane w głównym wątku aplikacji. Zachowanie użytkownika, który wykonuje takie akcje w jakimkolwiek innym wątku, zwykle jest dużym opóźnieniem lub nawet nie ma żadnego efektu. Większość kodu jest już uruchomiona w głównym wątku, więc zwykle nie musisz się tym martwić, ale w niektórych przypadkach to robisz. – manecosta

3

zaznacz 'viewWillAppear' kontrolera ParentViewController i 'viewWillDisappear' kontrolera currentViewcontroller. Upewnij się, że te dwie funkcje nie mają żadnych ciężkich obliczeń i alokacji pamięci w ramach.

+0

To jest poprawna odpowiedź w moim przypadku! – Jack

0

Spróbuj zmienić

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

a następnie spróbuj

if ([stan isEqualToString: @ "OK"]) {

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

jak ja nie wiem, jak duży jest twój JSON Obiekt może chwilę odpowiedzieć, a ponieważ wywołujesz ją ponownie po stwierdzeniu dziennika i robieniu czegoś innego przed powiedzeniem zwolnienia, może to być właśnie to.

Powiązane problemy