目前我正在尝试执行一些异步和并发任务,我正在使用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中这样做?
答案 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)
如果您有权访问请求所在的队列,则可以发出屏障块。
当你有一个异步队列时,一个障碍块会等待执行,直到所有的块在它运行之前发出。
如果您无法访问队列,那么最好的办法是保持计数。