【问题标题】:Completion blocks in for loopfor循环中的完成块
【发布时间】:2014-02-18 23:46:36
【问题描述】:

目前我正在尝试执行一些异步和并发任务,并且我正在使用 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中这样做吗?

【问题讨论】:

  • 您可以在完成块中保留一个运行总计,并在completedBlocks == [images count]时运行您的邮政编码。

标签: ios objective-c cocoa-touch cocoa


【解决方案1】:

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

- (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]

【讨论】:

    【解决方案2】:

    如果您有权访问请求进入的队列,则可以发出障碍块。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      • 1970-01-01
      • 2014-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多