dispatch_group_t - EXC_BAD_INSTRUCTION

Ram*_*sel 3 objective-c grand-central-dispatch

这是我第一次使用dispatch_group_t,我犯了一个简单的错误。dispatch_group_notify在任何异步调用返回之前被调用,因此甚至在第一个调用之前被调用dispatch_group_leave(group),然后抛出一个EXC_BAD_INSTRUCTION.

但是,我不知道为什么会发生这种情况。

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

dispatch_group_async(group, queue, ^{
    [self getCategoriesMainWithParameters:nil withSuccess:^(NSArray *objects) {
        [categoriesMain addObjectsFromArray:objects];
        dispatch_group_leave(group);
    } failure:^(NSError *error) {
        groupError = error;
        dispatch_group_leave(group);
    }];
});

dispatch_group_async(group, queue, ^{
    [self getCategoriesSubWithParameters:nil withSuccess:^(NSArray *objects) {
        [categoriesSub addObjectsFromArray:objects];
        dispatch_group_leave(group);
    } failure:^(NSError *error) {
        groupError = error;
        dispatch_group_leave(group);
    }];
});

dispatch_group_async(group, queue, ^{
    [self getCategoriesProductWithParameters:nil withSuccess:^(NSArray *objects) {
        [categoriesProduct addObjectsFromArray:objects];
        dispatch_group_leave(group);
    } failure:^(NSError *error) {
        groupError = error;
        dispatch_group_leave(group);
    }];
});

dispatch_group_notify(group,dispatch_get_main_queue(),^{
   ...
});
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 5

该函数dispatch_group_async在分派块时自动 \xe2\x80\x9centers\xe2\x80\x9d 组,并在分派块完成时自动 \xe2\x80\x9cleaves\xe2\x80\x9d 。但是您再次调用dispatch_group_leave,因此最终会产生太多 \xe2\x80\x9cleave\xe2\x80\x9d 调用,从而导致您描述的错误。

\n

人们应该调用dispatch_group_async(使用所有为您进行的 \xe2\x80\x9center\xe2\x80\x9d 和 \xe2\x80\x9cleave\xe2\x80\x9d 调用),或者在dispatch_group_enter异步调用之前手动调用并dispatch_group_leave在异步进程的完成处理程序。

\n

在这种情况下,因为您在分派块内调用异步任务,所以该dispatch_group_async模式将\xe2\x80\x99 无法工作。您需要dispatch_group_enter在调用异步方法之前手动执行此操作,然后让完成处理程序调用dispatch_group_leave,就像您所做的那样。当每个 \xe2\x80\x9center\xe2\x80\x9d 与 \xe2\x80\x9cleave\xe2\x80\x9d 匹配时,该组将收到通知。并且因为您调用的方法已经是异步的,所以您根本不需要使用dispatch_asyncor 。dispatch_group_async

\n

因此,它可能看起来像:

\n
dispatch_group_t group = dispatch_group_create();\n\ndispatch_group_enter(group);\n[self getCategoriesMainWithParameters:nil withSuccess:^(NSArray *objects) {\n    [categoriesMain addObjectsFromArray:objects];\n    dispatch_group_leave(group);\n} failure:^(NSError *error) {\n    groupError = error;\n    dispatch_group_leave(group);\n}];\n\ndispatch_group_enter(group);\n[self getCategoriesSubWithParameters:nil withSuccess:^(NSArray *objects) {\n    [categoriesSub addObjectsFromArray:objects];\n    dispatch_group_leave(group);\n} failure:^(NSError *error) {\n    groupError = error;\n    dispatch_group_leave(group);\n}];\n\ndispatch_group_enter(group);\n[self getCategoriesProductWithParameters:nil withSuccess:^(NSArray *objects) {\n    [categoriesProduct addObjectsFromArray:objects];\n    dispatch_group_leave(group);\n} failure:^(NSError *error) {\n    groupError = error;\n    dispatch_group_leave(group);\n}];\n\ndispatch_group_notify(group,dispatch_get_main_queue(),^{\n    ...\n});\n
Run Code Online (Sandbox Code Playgroud)\n