Perform UI Changes on main thread using dispatch_async or performSelectorOnMainThread?

Viewed 27806

Possible Duplicate:
Grand Central Dispatch (GCD) vs. performSelector - need a better explanation

To execute "stuff" on the main thread, should I use dispatch_async or performSelectorOnMainThread? Is there a preferred way, right/or wrong, and/or best practice?

Example: I'm performing some logic within the block of an NSURLConnection sendAsynchronousRequest:urlRequest method. Because I'm doing stuff to the main view such as presenting a UIAlertView I need to show the UIAlertView on the main thread. To do this I'm using the following code.

[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

    // code snipped out to keep this question short

    if(![NSThread isMainThread]) 
    {
        dispatch_async(dispatch_get_main_queue(), ^{
                    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Some Message" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
                    [alertView show];
        });
    }
}];

Within that same if(![NSThread isMainThread]) statement I also call some custom methods. The question is, should I use the dispatch_async method that I'm using above or is it better to use performSelectorOnMainThread instead? For example, full code below:

[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

    // code snipped out to keep this question short

    if(![NSThread isMainThread]) 
    {
        dispatch_async(dispatch_get_main_queue(), ^{
                    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Some Message" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
                    [alertView show];

            // call custom methods in dispatch_async?
            [self hideLoginSpinner];
        });

        // or call them here using performSelectorOnMainThread???
        [self performSelectorOnMainThread:@selector(hideLoginSpinner) withObject:nil waitUntilDone:NO];
    }
}];

FYI - If I DO NOT perform these actions on he main thread I see a few second delay when presenting the UIAlertView and I receive the following message in the debugger wait_fences: failed to receive reply: 10004003. I've learned that this is because you need to make changes to the UI on the main thread... In case someone is wondering why I'm doing what I'm doing...

1 Answers
Related