0

起初
我有这个如何等到异步调用齐全,包括完成块(AFNetworking)

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); 

然后我得到什么? 没有输出。

哪里出错?

回答

2

你可能没有得到任何输出,因为你的程序永远不会通过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之后 - 无论哪种方式都可以工作,但有时候我发现通过调用一个方法来保持我的代码更容易,而不是将所有的代码放在一个块中。如果你想在代码之间共享一些代码,这可能特别有用成功和失败块)。

+0

谢谢你的回答,我认为它也导致了僵局。但是'dispatch_group_wait'后面需要做的事情是登录。登录后,我可以返回YES或NO。但是如果我把这个日志放在成功处理程序的代码或方法中。它将异步运行,因此无法返回。 – Puttin 2013-03-25 02:56:39

+0

我会尝试一些同步代码。谢谢你的帮助。这种情况不应该使用异步代码。 – Puttin 2013-03-25 07:55:35