Chadams Chadams - 10 months ago 103
iOS Question

dismissViewControllerAnimated:completion: has a couple second delay

dismissViewControllerAnimated:completion: is working fine in my application, except for the delay between the dismissal.

[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];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"could not log you in" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];

In my console I can see echo'ed "DONE... ok", meaning the callback block was executed, however about 3-4 seconds later the modal view is finally dismissed.

What could be causing this delay?

Answer Source

If you don't guarantee your UI code is running on Main Thread it might run on some other and in that case, you will experience a few seconds delay!

You can add this to make sure that dismissal is ran on main thread:

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

Generally, this is not an issue as most of your code will already be running on main thread, since we mostly add code that runs from UIKit methods, like viewDidLoad and such. Those methods are guaranteed to be ran on the main thread.

The issue arises when you end up running code on another thread. One case where that can happen is for example on a completion block invocation of a networking library, where the request is done on background.