起初 我有这个
ZTCAPIClient *api = [ZTCAPIClient sharedClient];
__block BOOL sessionSuccess = NO;
//Get session
[api getPath:@"api-getsessionid.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id JSON) {
NSMutableDictionary *dict = [self dealWithZTStrangeJSON:JSON];
if ([dict count]) {
NSLog(..something..);
sessionSuccess = YES;
NSLog(@"inside:%u",sessionSuccess);
} else {
NSLog(@"ERROR: Get no session!");
sessionSuccess = NO;
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"ERROR: %@",error);
sessionSuccess = NO;
}];
[api.operationQueue waitUntilAllOperationsAreFinished];
NSLog(@"outside:%u",sessionSuccess);
但我会得到:
outside:0
inside:1
我知道这是异步的原因。 所以我在互联网上搜索,然后我发现了这个:wait until multiple operations executed - including completion block (AFNetworking)
所以我试试看:
ZTCAPIClient *api = [ZTCAPIClient sharedClient];
__block BOOL sessionSuccess = NO;
dispatch_group_t group = dispatch_group_create();
//Get session
dispatch_group_enter(group);
[api getPath:@"api-getsessionid.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id JSON) {
NSMutableDictionary *dict = [self dealWithZTStrangeJSON:JSON];
if ([dict count]) {
NSLog(..something..);
sessionSuccess = YES;
NSLog(@"inside:%u",sessionSuccess);
} else {
NSLog(@"ERROR: Get no session!");
sessionSuccess = NO;
}
dispatch_group_leave(group);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"ERROR: %@",error);
sessionSuccess = NO;
dispatch_group_leave(group);
}];
//[api.operationQueue waitUntilAllOperationsAreFinished];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);
DLog(@"outside:%u",sessionSuccess);
然后我什么都没得到......
没有输出。
哪里错了?
答案 0 :(得分:3)
你可能没有得到任何输出,因为你的程序永远不会超过调用dispatch_group_wait
。如果确实如此,那么你会看到“外部”日志声明。
如果dispatch_group_wait
永远不会返回,那么组中仍然必须存在某些内容。在示例代码中,使用dispatch_group_enter
向组中添加一项内容,然后在使用dispatch_group_leave
的api调用的成功或失败处理程序中将其删除。这意味着由于某种原因没有调用dispatch_group_leave
。
我怀疑没有调用块的原因是它们将在外部代码运行的同一个调度队列上异步调用。如果是这种情况,则在dispatch_group_wait
返回之前它们无法运行,dispatch_group_wait
在块运行之前无法返回。这称为deadlock。 (编辑:或者,可能是调用成功或失败块的程序的某些部分是导致死锁的部分。无论哪种方式,结果是从dispatch_group_wait
开始无法调用块。永远不会回来。)
另一种可能性是方法-dealWithZTStrangeJSON:
由于某种原因永远不会返回。如果是这种情况,那么将调用成功块(您可以在其第一行设置断点以进行验证),但它永远不会进入dispatch_group_leave
。
在任何一种情况下,我都建议您考虑以另一种方式解决问题,而不是等待操作完成。也许你可以在dispatch_group_wait
在成功处理程序内部返回之后执行你计划要做的事情(或者另一种思考方式是成功或失败处理程序可以调用一个方法来完成你的事情'目前正在dispatch_group_wait
之后做 - 任何一种方式都可行,但有时我发现通过调用方法而不是将所有代码放在一个块中来保持我的代码组织更容易。这可能特别有用如果你想在成功和失败块之间共享一些代码。)