Search code examples
iosobjective-cgrand-central-dispatchnsoperationqueuedispatch-async

How to execute second dispatch_async when previous first dispatch_async is finished?


I would like to add a dispatch_async sequentially but I would like them not to be launched randomly. I would like for example :

dispatch_async 1 begins...
dispatch_async 1 ends.

dispatch_async 2 begins...
dispatch_async 2 ends.

dispatch_async 3 begins...
dispatch_async 3 ends.

I need to update a sqlite, and the informations in the first dispatch are necessary for the second dispatch...

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"%@",[connection currentRequest]);

    NSLog(@"connectionDidFinishLoading");
    NSError* error;
    NSString *responseKey = [self getResponseKey:connection];

    NSDictionary* response = [NSJSONSerialization JSONObjectWithData:[receivedData objectForKey:responseKey] options:kNilOptions error:&error];
    //NSLog(@"%@", response);

    if (error)
    {
        NSLog(@"Error: %@", error);
        NSLog(@"Error: Response strange format, not an NSArray and not a NSString!\n%@", [[NSString alloc] initWithData:[receivedData objectForKey:responseKey] encoding:NSUTF8StringEncoding]);
    }

    NSLog(@"connection url : %@", connection.currentRequest.URL);

    if ([[NSString stringWithFormat:@"%@", [connection currentRequest]] rangeOfString:@"getSynchroGuest?"].location != NSNotFound) 
    {
        NSLog(@"response success");
        if ([[response valueForKey:@"lignes"] isKindOfClass:[NSArray class]])
        {
            if ([[response valueForKey:@"lignes"] count] > 0)
            {
                dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
                    //Background Thread

                [self fillDataBaseWithDict:response];

                nbTotal = nbTotal + PACKET_FOR_SYNC;

                [self WebServiceSynchroGuest:self.activityIndicator withSynchroBtn:synchroBtn withNbTotal:nbTotal];
                                 });

            }
        }
...

Thanks in advance.

SOLUTION:
                dispatch_async(serialDispatchQueue, ^{
                    [self fillDataBaseWithDict:response];
                    nbTotal = nbTotal + PACKET_FOR_SYNC;

                    dispatch_async(dispatch_get_main_queue(), ^(void){
                    [self WebServiceSynchroGuest:self.activityIndicator withSynchroBtn:synchroBtn withNbTotal:nbTotal];
                    });
                });

Solution

  • define your own serial queue

    and add code like this

     dispatch_queue_t yourSerialQueue = dispatch_queue_create("com.testcompany.testproduct.testserialqueue", DISPATCH_QUEUE_SERIAL);
     dispatch_async(yourSerialQueue, ^{ /* first task */ });
     dispatch_async(yourSerialQueue, ^{ /* second task to be executed after first task */ });
    

    serial queue guarantees that the tasks will be exevuted in the order they are submitted and in a serial manner(one at a time)