我有两个完成调用的方法,并希望在此之后调用dispatch_group_notify块。这在第一次完成后有效,但在第二次完成后无效。我需要在第二次通话后才能使用。
这是我的代码:
method1WithCompletion:和method2WithCompletion:将有2个响应,首先是本地数据,后来发出请求api并返回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
});
不确定如何正确设置
答案 0 :(得分:0)
据我所知,这些完成块将被调用两次,一次用于本地数据,第二次用于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);