GCD等待队列中的所有任务完成

时间:2015-07-08 10:34:23

标签: objective-c cocoa cocoa-touch grand-central-dispatch

在我的应用程序中,我有照片上传功能,我希望我的主队列等到照片上传完成。这是我的代码:

    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 

但这没效果,我的程序继续执行而不等待照片上传完成。

1 个答案:

答案 0 :(得分:2)

因为您在块中使用saveInBackgroundWithBlock:方法,对吗?

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

Saves the file asynchronously and executes the given block.

如果您确实要等待后台处理的块,则需要为方法调用dispatch_group_enterdispatch_group_leave,如下所示。

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

    ...

}];

顺便说一下,

  

我希望我的主要队列等到照片上传完成

这不是一个好主意。不要阻塞主线程(主队列)。

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

  

请务必限制您在应用主线程上执行的工作类型。主线程是您的应用处理触摸事件和其他用户输入的位置。为确保您的应用始终对用户做出响应,您绝不应使用主线程执行长时间运行或可能无限制的任务,例如访问网络的任务。