【问题标题】:race condition by using __block使用 __block 的竞争条件
【发布时间】:2017-06-08 14:40:12
【问题描述】:

我有一个 PHAsset 列表,我需要获取它们的关联 URL 并对每个 URL 执行一些操作。处理完所有资产后,我需要执行另一项任务。我尝试使用 __block 来计算处理的资产,但由于竞争条件它不可靠。有没有更好的方法来了解所有资产何时被处理?

    PHFetchResult* photosAsset = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions2];
    __block int count = 0;

    for (int i = 0; i < photosAsset.count; ++i) {
        [[PHImageManager defaultManager] requestAVAssetForVideo:[photosAsset objectAtIndex:i] options:nil resultHandler:
         ^(AVAsset *avAsset, AVAudioMix *audioMix, NSDictionary *info) {
             NSURL *url = [(AVURLAsset *)avAsset URL];
             // then do something with the url here...

             ++count;
             NSLog(@"%d", count);
             if (count == photosAsset.count) {
                 NSLog(@"FINISHED!");
             }
        }];
    }

【问题讨论】:

  • 可能是dispatch_group_enter()dispatch_group_leave()dispatch_group_notify()

标签: ios objective-c asynchronous objective-c-blocks phasset


【解决方案1】:

所以这里是基于@Larme 建议的解决方案:

    dispatch_group_t group = dispatch_group_create();

    for (int i = 0; i < photosAsset.count; ++i) {
        dispatch_group_enter(group);
        [[PHImageManager defaultManager] requestAVAssetForVideo:[photosAsset objectAtIndex:i] options:nil resultHandler:
         ^(AVAsset *avAsset, AVAudioMix *audioMix, NSDictionary *info) {
             dispatch_group_leave(group);
         }];
    }

    dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
        NSLog(@"FINISHED!");
    });

    dispatch_release(group);

【讨论】:

    猜你喜欢
    • 2011-12-12
    • 2019-02-10
    • 2015-04-28
    • 1970-01-01
    • 2021-10-10
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多