dispatch_group_notify 第二次完成调用后

dispatch_group_notify after second completion call

我有两个完成调用的方法,然后想调用 dispatch_group_notify 块。这在第一次完成后起作用,但在第二次完成后不起作用。我也需要在第二次通话后让它工作。

这是我的代码:

method1WithCompletion: 和 method2WithCompletion: 将有 2 个响应,首先是本地数据,然后是请求 api 和 return api 数据

  dispatch_group_t requestGroup = dispatch_group_create();

  dispatch_group_enter(requestGroup);
 [self method1WithCompletion:^(NSArray *items) {
//here I will get 2 responses (first from local storage, second from api)
dispatch_group_leave(requestGroup);
 }];

  dispatch_group_enter(requestGroup);
 [self method2WithCompletion:^(NSArray *items) {
//here I will get 2 responses (first from local storage, second from api)
dispatch_group_leave(requestGroup);
 }];

 // now this will only be called once the two "enter" calls are balanced with the corresponding "leave" calls

 dispatch_group_notify(requestGroup, dispatch_get_main_queue(), ^{
//completion
//that should be called after method 1 and method 2 executed with local data,           and after they executed with api data
 });

不确定如何正确设置

我知道这些完成块将分别被调用两次,一次用于本地数据,第二次用于 API 数据。并且您希望在两个本地调用完成时调用通知块,并在两个 API 调用完成时再次调用。

为此,你需要两个调度组,你可以这样做:

dispatch_group_t requestGroupLocal = dispatch_group_create();
dispatch_group_t requestGroupAPI = dispatch_group_create();

dispatch_group_enter(requestGroupLocal);
dispatch_group_enter(requestGroupAPI);
__block NSInteger count1 = 0;
[self method1WithCompletion:^(NSArray *items) {
    if (count1 == 0) {
        dispatch_group_leave(requestGroupLocal);
        count1++;
    } else {
        dispatch_group_leave(requestGroupAPI);
    }
}];

dispatch_group_enter(requestGroupLocal);
dispatch_group_enter(requestGroupAPI);
__block NSInteger count2 = 0;
[self method2WithCompletion:^(NSArray *items) {
    if (count2 == 0) {
        dispatch_group_leave(requestGroupLocal);
        count2++;
    } else {
        dispatch_group_leave(requestGroupAPI);
    }
}];

dispatch_block_t completion = ^{
    // do whatever you want when each group finishes
};

dispatch_group_notify(requestGroupLocal, dispatch_get_main_queue(), completion);
dispatch_group_notify(requestGroupAPI, dispatch_get_main_queue(), completion);

或者,更好的是,与其依赖那些神秘的计数器,不如向块中添加一个参数来指示它是否是本地调用:

dispatch_group_t requestGroupLocal = dispatch_group_create();
dispatch_group_t requestGroupAPI = dispatch_group_create();

dispatch_group_enter(requestGroupLocal);
dispatch_group_enter(requestGroupAPI);
[self method1WithCompletion:^(NSArray *items, BOOL isLocal) {
    if (isLocal) {
        dispatch_group_leave(requestGroupLocal);
    } else {
        dispatch_group_leave(requestGroupAPI);
    }
}];

dispatch_group_enter(requestGroupLocal);
dispatch_group_enter(requestGroupAPI);
[self method2WithCompletion:^(NSArray *items, BOOL isLocal) {
    if (isLocal) {
        dispatch_group_leave(requestGroupLocal);
    } else {
        dispatch_group_leave(requestGroupAPI);
    }
}];

dispatch_block_t completion = ^{
    // do whatever you want when each group finishes
};

dispatch_group_notify(requestGroupLocal, dispatch_get_main_queue(), completion);
dispatch_group_notify(requestGroupAPI, dispatch_get_main_queue(), completion);

坦率地说,这种两次调用完成处理程序的模式非常不典型,有点可疑。我可以想象当前设计背后的意图,但我倾向于放弃它。相反,我宁愿看到本地和 API 再现的单独方法,它们只调用它们的完成处理程序一次:

dispatch_group_t requestGroupLocal = dispatch_group_create();

dispatch_group_enter(requestGroupLocal);
[self methodLocal1WithCompletion:^(NSArray *items) {
    dispatch_group_leave(requestGroupLocal);
}];

dispatch_group_enter(requestGroupLocal);
[self methodLocal2WithCompletion:^(NSArray *items) {        
    dispatch_group_leave(requestGroupLocal);
}];

dispatch_group_t requestGroupAPI = dispatch_group_create();

dispatch_group_enter(requestGroupAPI);
[self methodAPI1WithCompletion:^(NSArray *items) {        
    dispatch_group_leave(requestGroupAPI);
}];

dispatch_group_enter(requestGroupAPI);
[self methodAPI2WithCompletion:^(NSArray *items) {        
    dispatch_group_leave(requestGroupAPI);
}];

dispatch_block_t completion = ^{
    // do whatever you want when each group finishes
};

dispatch_group_notify(requestGroupLocal, dispatch_get_main_queue(), completion);
dispatch_group_notify(requestGroupAPI, dispatch_get_main_queue(), completion);

或者,如果您真的只需要方法 1 和方法 2 的一个方法,那么将 local 设为参数,但再次编写仅调用其完成处理程序一次的方法:

dispatch_group_t requestGroupLocal = dispatch_group_create();

dispatch_group_enter(requestGroupLocal);
[self method1Local:true completion:^(NSArray *items) {
    dispatch_group_leave(requestGroupLocal);
}];

dispatch_group_enter(requestGroupLocal);
[self method2Local:true completion:^(NSArray *items) {
    dispatch_group_leave(requestGroupLocal);
}];

dispatch_group_t requestGroupAPI = dispatch_group_create();

dispatch_group_enter(requestGroupAPI);
[self method1Local:false completion:^(NSArray *items) {
    dispatch_group_leave(requestGroupAPI);
}];

dispatch_group_enter(requestGroupAPI);
[self method2Local:false completion:^(NSArray *items) {
    dispatch_group_leave(requestGroupAPI);
}];

dispatch_block_t completion = ^{
    // do whatever you want when each group finishes
};

dispatch_group_notify(requestGroupLocal, dispatch_get_main_queue(), completion);
dispatch_group_notify(requestGroupAPI, dispatch_get_main_queue(), completion);