在IOS上,我需要获取一组选定图像的元数据。但是,由于图像已备份到iCloud,因此有时可能会立即返回(缓存),有时可能需要一两秒钟。
for循环快速运行,我可以等待所有图像被处理后再前进。但是它们仍然是并行获取的。如何通过等待块完成然后再移至下一张图像来使for循环顺序运行。
// Step 4: Fetch Details like Metadata for this batch
-(void) getDetailsForThisBatchOfNewAssets:(NSMutableArray*) mArrBatchOfNewAssets
withCompletionHandler:(blockReturnsMArrAndMArr) blockReturns{
NSLog(@"%s with arraySize of %lu",__PRETTY_FUNCTION__, (unsigned long)[mArrBatchOfNewAssets count] );
long assetCount = [mArrBatchOfNewAssets count];
NSMutableArray *mArrNewAssetsAndDetails = [[NSMutableArray alloc] init];
NSMutableArray *mArrNewAssetFailed = [[NSMutableArray alloc] init];
if(assetCount == 0){
NSLog(@" Looks like there are no NEW media files on the device.");
return;
}
else
NSLog(@"found %ld assets in all that need to be backed up", assetCount);
dispatch_group_t groupForLoopGetDetails = dispatch_group_create();
for(long i = 0 ; i < assetCount; i++){
PHAsset *currentAsset = [[mArrBatchOfNewAssets objectAtIndex:i] objectForKey:@"asset"];
NSString *mediaIdentifier = [[[currentAsset localIdentifier] componentsSeparatedByString:@"/"] firstObject];
[mArrIdentifiersInThisBatch addObject:mediaIdentifier];
dispatch_group_enter(groupForLoopGetDetails);
[mediaManager getDetailedRecordForAsset:currentAsset
withCompletionHandler:^(NSMutableDictionary *mDicDetailedRecord, NSMutableDictionary *mDicRecordForError)
{
if(mDicRecordForError[@"error"]){
[mArrNewAssetFailed addObject:mDicRecordForError];
NSLog(@"Position %ld - Failed to fetch Asset with LocalIdentifier: %@, adding it to Failed Table. Record: %@",i,[currentAsset localIdentifier], mDicRecordForError);
} else {
[mArrNewAssetsAndDetails addObject:mDicDetailedRecord ];
NSLog(@"Position %ld - added asset with LocalIdentifier to mArrNewAssetsAndDetails %@",i,[currentAsset localIdentifier]);
}
dispatch_group_leave(groupForLoopGetDetails);
}];
} // end of for loop that iterates through each asset.
dispatch_group_notify(groupForLoopGetDetails, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"Completed gathering details for this batch of assets for backup. Count : %lu and failed Media count: %lu",(unsigned long)[mArrNewAssetsAndDetails count], (unsigned long)[mArrNewAssetFailed count]);
blockReturns(mArrNewAssetsAndDetails,mArrNewAssetFailed);
});
}
我已经浏览了关于此主题的几个问题,但仍然没有弄清楚如何使它按顺序运行。
我不想为此方法进行“自我调用”,因为在达到此方法之前,我已经在另一个地方进行了“自我调用”,并且我的代码现在正越来越多地被通知和捕获,因为
答案 0 :(得分:0)
假设getDetailedRecordForAsset
的完成处理程序在另一个线程上调用,则可以在循环内使用信号量阻止执行(注意:不要在主线程上执行此操作)在等待完成处理程序时。
然后在循环内删除调度组的内容:
在调用getDetailedRecordForAsset
之前创建信号量,如下所示:dispatch_semaphore_t semaphore = dispatch_semaphore_create( 0);
作为完成处理程序调用{{1}}
在调用dispatch_semaphore_signal( semaphore);
之后立即使用getDetailedRecordForAsset
因此循环的结构如下:
dispatch_semaphore_wait( semaphore, DISPATCH_TIME_FOREVER);