for循环中的完成块

时间:2014-02-18 23:46:37

标签: ios objective-c cocoa-touch cocoa

目前我正在尝试执行一些异步和并发任务,我正在使用Azures blob上传所有图像,但关注的是,对于每个blob我需要获得SASURL然后上传图像。此外,另一方面是我希望上传完成的图像的所有操作,并因此将最终上载发送到数据库。虽然我可以更早地将操作发送到数据库,但没有完成图像的确认,但我只是想确保操作确实完成。

以下是SASURL块的代码。

- (void)storageServiceBlob:(NSArray*)images
{
    StorageService *storageService = [StorageService getInstance];
    NSLog(@"%@",[storageService containers]);
    NSLog(@"%@",[storageService blobs]);

    for (int i = 0; i < [images count]; i++) {

        NSString *file_name = [images objectAtIndex:i];
        NSString *result = [self imageName:file_name];
        NSLog(@"Final: %@", result);

        [storageService getSasUrlForNewBlob:result forContainer:@"misccontainer" withCompletion:^(NSString *sasUrl) {

            NSLog(@"%@",sasUrl);
            [self postBlobWithUrl:sasUrl Image:[images objectAtIndex:i]];
        }];
    }
}

我想以某种方式在组中使用gcd来确定在组中调用所有完成块后,它会执行Post方法。无论如何在gcd中这样做?

2 个答案:

答案 0 :(得分:5)

许多方法可以做到这一点。这是一个:

- (void)storageServiceBlob:(NSArray *)imageFilenames
{
    StorageService *storageService = [StorageService getInstance];
    __block NSMutableSet *remainingImageFilenames = [NSMutableSet setWithArray:imageFilenames];

    for (NSString *imageFilename in imageFilenames) {
        NSString *imageName = [self imageNameForImageFilename:imageFilename];

        [storageService getSasUrlForNewBlob:imageName forContainer:@"misccontainer" withCompletion:^(NSString *sasUrl) {
            [self postBlobWithUrl:sasUrl imageFilename:imageFileName];
            [remainingImageFilenames removeObject:imageFilename];
            if ([remainingImageFilenames count] == 0) {
                // you're done, do your thing
            }
        }];
    }
}

一些提示:

  • 小心命名。那里似乎有些含糊不清。

  • 通常,惯用的方法名称参数以小写字母开头,例如myMethodWithThis:andThat:,而非MyMethodWithThis:AndThat:

  • 快速枚举,例如for (id obj in array)是你的朋友。学习并使用它。

  • 您可以将[array objectAtIndex:1]缩短为array[1]

答案 1 :(得分:1)

如果您有权访问请求所在的队列,则可以发出屏障块。

当你有一个异步队列时,一个障碍块会等待执行,直到所有的块在它运行之前发出。

如果您无法访问队列,那么最好的办法是保持计数。