Search code examples
iosios5xcode4queuegrand-central-dispatch

iOS: How do I get my blocks to execute without interrupting each other?


I have a process that I'm trying to create where I download different xml files and parse them from a website. At the moment I can get them to all work by using...

dispatch_async(dispatch_get_current_queue(),^ { [self updatePersons]; });
dispatch_async(dispatch_get_current_queue(),^ { [self updatePlaces]; });
dispatch_async(dispatch_get_current_queue(),^ { [self updatePositions]; });
dispatch_async(dispatch_get_current_queue(),^ { [self updateContacts]; });

This locks up the main thread because I'm using dispatch_get_current_queue. How can I get these to execute without interrupting each other which seems to be the case when trying the method below.

dispatch_async(dispatch_get_global_queue(0,0),^ { [self updatePersons]; });

The full version of my code I'm using is below, but what happens according to my Log output is they execute at the same time (which I get is kinda the purpose if I understand everything right); however, the code for them never really finishes... I cannot tell if everything is getting parsed or not through the Log Output and the main screen stays frozen. The log only shows part of the logs it should be showing... seems to be interrupted by the other process's NSLog messages.

dispatch_async(dispatch_get_global_queue(0,0),^ { [self updatePersons]; });
dispatch_async(dispatch_get_global_queue(0,0),^ { [self updatePlaces]; });
dispatch_async(dispatch_get_global_queue(0,0),^ { [self updatePositions]; });
dispatch_async(dispatch_get_global_queue(0,0),^ { [self updateContacts]; });

dispatch_async(dispatch_get_global_queue(-2,0),^ { 

            dispatch_async(dispatch_get_main_queue(),^  {[self setBottomBarToUpdated]; });
 });

I'm trying to create a way for the app to pull down the information through each of the functions above, while updating the user on the progress while it's executing by a label on the bottom bar. I have the updating the text working fine it seems by using the below code in each of the four functions...

dispatch_async(dispatch_get_main_queue(),^ {
         [self setBottomBarToUpdating:@"Updating Places..."];
});

If anyone can offer help to the proper way to use the queues so my app doesn't lock up I'd greatly appreciate it. Thanks!


Solution

  • If you create you own private concurrent dispatch queue, then you can use a "barrier block". This block will be executed only when all other previously submitted blocks are finished.

    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    
    // These blocks are executed concurrently:
    dispatch_async(queue, ^ { [self updatePersons]; });
    dispatch_async(queue, ^ { [self updatePlaces]; });
    // ...
    
    dispatch_barrier_async(queue, ^ {
        // This will be executed when all previous blocks are finished.
        dispatch_async(dispatch_get_main_queue(), ^{
            [self setBottomBarToUpdated];
        });
    });