ios - 如何同时执行多个异步方法并在它们全部完成时获得回调?

标签 ios objective-c swift asynchronous grand-central-dispatch

我编写了以下代码,但我不确定它是否按预期方式工作:

func loadAssets(assets: [String: [String]]) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0) {
        let group = dispatch_group_create()
        for (assetType, ids) in assets {
            switch(assetType) {
            case Settings.imageAssetType:
                for id in ids {
                    dispatch_group_enter(group)
                    Assets.fetchImage(id) { _ in
                        dispatch_group_leave(group)
                    }
                }
            case Settings.soundAssetType:
                for id in ids {
                    dispatch_group_enter(group)
                    Assets.fetchSound(id) { _ in
                        dispatch_group_leave(group)
                    }
                }
            case Settings.jsonAssetType:
                for id in ids {
                    dispatch_group_enter(group)
                    Assets.fetchJSON(id) { _ in
                        dispatch_group_leave(group)
                    }
                }
            case default:
                for id in ids {
                    dispatch_group_enter(group)
                    Assets.fetchClip(id) { _ in
                        dispatch_group_leave(group)
                    }
                }
            }
        }
        dispatch_group_notify(group, main, self.assetsDidLoad)
    }
}

基本上,一种使用字典加载所有 Assets 的方法,其键值在其键中包含 Assets 类型,并将 Assets ID 列表作为值。然后,我为每种类型的 Assets 遍历所有这些 Assets ID,并调用一种方法来获取 Assets 。 (我不确定获取方法是否完全异步运行,它们可能也有部分代码是同步的,这些方法将加载 Assets )。

无论如何,我想做的是在所有这些获取方法都完成后调用方法 assetsDidLoad(),因此所有 Assets 都已加载,这就是我尝试使用调度组功能的原因。但是,我对这个调度代码还很陌生,我不确定我现在所做的是否适合我的目的。

如果有人能指出这是否可以,或者我应该如何处理这个问题,我将不胜感激。我什至会很感激 Objective-C 的回应。

谢谢!

最佳答案

您的代码看起来是正确的(假设您所有的 fetch 方法都保证执行它们的代码块)。如果 assets 为空,您的通知 block 将立即触发。 dispatch_group_enterdispatch_group_leave只需要平衡,就可以在队列中调用。

作为引用,这里是我用来测试一些不同情况(在 Objective-C 中)的一些代码:

dispatch_queue_t queue = dispatch_queue_create("com.Test.TestQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, queue, ^
{
    sleep(3);
    printf("\nFirst done!");
});

dispatch_group_async(group, queue, ^
{
    sleep(1);
    printf("\nSecond done!");

    dispatch_group_enter(group);
    sleep(5);
    printf("\nNested done!");
    dispatch_group_leave(group);

});

dispatch_group_async(group, queue, ^
{
    sleep(2);
    printf("\nThird done!");
});

dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
    sleep(10);
    printf("\nAsync done!");
    dispatch_group_leave(group);
});

dispatch_group_notify(group, dispatch_get_main_queue(), ^
{
    printf("\nAll done!");

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Message" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:nil];
    [alertView show];
});

在调试器中显示警告结束:

Second done!
Third done!
First done!
Nested done!
Async done!
All done!

关于ios - 如何同时执行多个异步方法并在它们全部完成时获得回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33046501/

相关文章:

Swift 在可空性可用之前使用 Implicitly Unwrapped Optional

ios - AVFoundation 导出方向错误

ios - 新 iTunes 连接中的 IPA 大小错误?

ios - NSDateFormatter 没有输出我所期望的

ios - xcode - 大写标签输出

ios - 我的 UIStackView 框架彼此堆叠

ios - 从命令行读取 ios 设备上的应用程序的 qDebug 输出

ios - 当 uisearchDisplayController 激活时,导航栏中的搜索栏动画出现问题

ios - 在 iOS7 中缩放 UIWebView

ios - Swift:基类数组不调用子类函数实现