0

一开始
我有这个

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

我知道这是异步的原因。于是在网上搜了一下,后来发现是这样的:等到多个操作执行——包括完成块(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);

然后我什么都没有……没有输出。

哪里错了?

4

1 回答 1

3

您可能没有得到任何输出,因为您的程序永远不会超过对dispatch_group_wait. 如果确实如此,那么您将看到“外部”日志语句。

如果dispatch_group_wait永远不会返回,那么组中肯定还有一些东西。在您的示例代码中,您将一件事添加到组中dispatch_group_enter,然后在 api 调用的成功或失败处理程序中将其删除dispatch_group_leave。这意味着dispatch_group_leave由于某种原因没有被调用。

我怀疑这些块没有被调用的原因是它们将在运行外部代码的同一个调度队列上异步调用。如果是这种情况,那么它们在返回之前无法运行,dispatch_group_wait并且dispatch_group_wait在块运行之前无法返回。这称为死锁。(编辑:或者,调用成功或失败块的程序的某些部分可能是导致死锁的部分。无论哪种方式,结果都是块不能被调用,因为dispatch_group_wait永远不会返回。)

另一种可能性是该方法-dealWithZTStrangeJSON:由于某种原因永远不会返回。如果是这种情况,则将调用成功块(您可以在其第一行设置断点以进行验证),但它永远不会到达dispatch_group_leave.

无论哪种情况,我都建议您考虑以另一种方式解决您的问题,而不是等待操作完成。也许您可以在成功处理程序内部返回后执行您计划做的事情dispatch_group_wait(或者另一种思考方式是成功或失败处理程序可以调用一个方法来执行您当前正在执行的操作dispatch_group_wait——无论哪种方式都行,但有时我发现通过调用一个方法而不是将所有代码放在一个块中更容易保持我的代码井井有条。如果你想在成功之间共享一些代码,这可能特别有用和故障块)。

于 2013-03-25T02:11:05.483 回答