dispatch_group_t - EXC_BAD_INSTRUCTION

时间:2015-02-12 01:20:52

标签: 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(),^{
   ...
});

1 个答案:

答案 0 :(得分:3)

函数dispatch_group_async在调度块时自动进入组,并在调度块返回时离开。当块本身调用异步方法时,这不能很好地工作。

正如您所正确识别的那样,在处理异步方法时,您必须手动输入和离开组。但是,不应该使用dispatch_group_async来输入组(因为它会在调度块返回时自动离开组),而是在调用异步方法然后调用完成处理程序之前手动dispatch_group_enter dispatch_group_leave,就像你一样。当每个“输入”与“离开”匹配时,将通知该组。

因此,它可能看起来像:

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