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