Objective c 调度组-执行错误指令

Objective c 调度组-执行错误指令,objective-c,grand-central-dispatch,Objective C,Grand Central Dispatch,这是我第一次使用dispatch\u group\t,我犯了一个简单的错误。dispatch\u group\u notify在任何异步调用返回之前被调用,因此在第一个dispatch\u group\u leavegroup之前就被调用了,后者随后抛出EXC\u BAD\u指令 然而,我不知道为什么会这样 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); di

这是我第一次使用dispatch\u group\t,我犯了一个简单的错误。dispatch\u group\u notify在任何异步调用返回之前被调用,因此在第一个dispatch\u group\u leavegroup之前就被调用了,后者随后抛出EXC\u BAD\u指令

然而,我不知道为什么会这样

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(),^{
   ...
});
函数dispatch\u group\u async在调度块时自动“进入”组,并在调度块完成时自动“离开”。但是您再次调用dispatch\u group\u leave,因此您最终会接到太多的“leave”呼叫,从而导致您描述的错误

在为您进行的所有“enter”和“leave”调用中,应该调用dispatch\u group\u async,或者在异步调用之前手动调用dispatch\u group\u enter,并在异步进程的完成处理程序中调用dispatch\u group\u leave

在这种情况下,因为您正在调度块内调用异步任务,所以调度组异步模式将不起作用。您希望在调用异步方法之前手动分派\u group\u enter,然后让完成处理程序调用dispatch\u group\u leave,正如您所做的那样。当每个“进入”都与“离开”匹配时,将通知该组。而且因为您正在调用的方法已经是异步的,所以根本不需要使用dispatch\u async或dispatch\u group\u async

因此,它可能看起来像:

dispatch_group_t group = dispatch_group_create();

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

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

dispatch_group_enter(group);
[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(),^{
    ...
});

看,我解释了引擎盖下面的问题。那你为什么要在这里排队?你不需要。它是从原始代码片段中遗留下来的。我已将其删除。如果您离开调度组的次数超过输入的次数,这也会显示出来。不要忘记删除您的测试/存根/临时代码@绝对是。这就是问题的根本原因,因为dispatch\u group\u async会自动“进入”和“离开”,因此OP的原始代码片段中没有相应dispatch\u group\u enter的额外dispatch\u group\u leave会导致太多的“离开”调用。我试图澄清我的答案。