Chlebta
Chlebta

Reputation: 3110

GCD wait until all task in queue are finished

In my app I got photo upload function and I want my main queue wait until photo upload is done. Here's my code :

    dispatch_group_t groupe = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("com.freesale.chlebta.photoUplaod", 0);

dispatch_group_async(groupe, queue, ^{

    //Upload photo in same array with annonce
    //++++++++++++++++++++++++++++++++++++++
    if(!_annonce)
        [KVNProgress updateStatus:@"جاري رفع الصور"];

    __block NSInteger numberPhotoToUpload = _photoArray.count - 1;

    for (int i = 1; i < _photoArray.count; i++) {
        //check if image is asset then upload it else just decrement the photo numver because it's already uploaded
        if ( [[_photoArray objectAtIndex:i] isKindOfClass:[ALAsset class]]){
            ALAsset *asset = [_photoArray objectAtIndex:i];

            NSData *imageData = UIImageJPEGRepresentation([UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]], 0.6);

            PFFile *imageFile = [PFFile fileWithName:@"image.png" data:imageData];
            [imageFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
                if (succeeded)
                    [annonce addUniqueObject:imageFile forKey:@"photo"];
                else
                    NSLog(@"Error image upload \n image :%i \n error:  %@",i, error);

                    numberPhotoToUpload --;
            }];
        } else
            numberPhotoToUpload --;

    }

});

//Wait until Photo Upload Finished

dispatch_group_wait(groupe, DISPATCH_TIME_FOREVER);

// Some other Operation 

But this didn't worked, my program continue execution without waiting photo upload to be finished.

Upvotes: 0

Views: 952

Answers (1)

Kazuki Sakamoto
Kazuki Sakamoto

Reputation: 13999

Because you are using saveInBackgroundWithBlock: method in the block, right?

https://parse.com/docs/osx/api/Classes/PFFile.html#//api/name/saveInBackgroundWithBlock:

Saves the file asynchronously and executes the given block.

You need to call dispatch_group_enter and dispatch_group_leave for the method as the following if you really want to wait the background-processed block.

dispatch_group_enter(groupe);
[imageFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
    dispatch_group_leave(groupe);

    ...

}];

By the way,

I want my main queue wait until photo upload is done

It's not a good idea. Don't block the main thread (the main queue).

App Programming Guide for iOS - Performance Tips - Move Work off the Main Thread

Be sure to limit the type of work you do on the main thread of your app. The main thread is where your app handles touch events and other user input. To ensure that your app is always responsive to the user, you should never use the main thread to perform long-running or potentially unbounded tasks, such as tasks that access the network.

Upvotes: 1

Related Questions