如何在异步块内使用dispatch_group_async并等待dispatch_group_wait?涉及到IT技术。

3

我有一段代码,大致如下:

[SVProgressHUD show];
[imageGenerator generateCGImagesAsynchronouslyForTimes:times
                completionHandler:^(CMTime requestedTime, ...) {
                    dispatch_group_async(queueGroup, queue, ^{
                        // Do stuff
                });
}];

dispatch_group_wait(queueGroup, DISPATCH_TIME_FOREVER);
[SVProgressHUD dismiss];

基本上,显示加载动画HUD并从资产开始生成图像缩略图,然后在完成后隐藏HUD。我使用了一个调度组,因为我希望在隐藏HUD之前确保所有缩略图都已生成。
但是当我运行它时,HUD立即消失。我猜这是由于generateCGImagesAsynchronouslyForTimes: completionHandler:的异步特性--dispatch_group_wait在completionHandler内的第一个dispatch_group_async之前被调用。
有什么优雅的方法可以解决这个问题吗?谢谢。

完成块只有在所有图片加载完毕后才会被调用,为什么不把取消也放在里面呢? - Peter Foti
你能发布函数generateCGImagesAsynchronouslyForTimes的实现吗? - Matteo Gobbi
@PeterFoti 对于混淆感到抱歉,generateCGImagesAsynchronouslyForTimes的工作方式是对于每个生成的缩略图都会调用completionHandler,这意味着每次生成缩略图时都会调用dispatch_group_wait。我们只希望它被调用一次,不是吗? - Vlad
这里是函数。基本上,你传递一个时间戳的NSArray,处理程序会异步地为生成的每个缩略图调用一次:https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AVAssetImageGenerator_Class/Reference/Reference.html#//apple_ref/occ/instm/AVAssetImageGenerator/generateCGImagesAsynchronouslyForTimes:completionHandler: - Vlad
1
但是你知道要创建的图像数量,因此当完成块被调用以创建最后一个图像时,可以关闭HUD。 - Martin R
1个回答

9

将这个方法看作是对线程可用的静态计数器,因此当您进入一个组时,计数器会增加,当该块返回时,计数器会减少...

当计数器为0时,它将调用一个块来执行。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();

while(someCondition)
{
    dispatch_group_enter(group);
   [SomeClassThatLoadsOffTheInternet getMyImages:^{

        // do something with these.
        dispatch_group_leave(group);

    });
}

dispatch_group_notify(group, queue, ^{
    // do something when all images have loaded
});

这是你考虑的吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接