簡體   English   中英

如何等待直到異步調用完成,包括完成塊(AFNetworking)

[英]How to wait until a async call complete, including completion block (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

我知道這是異步原因。 因此,我在Internet上進行搜索,然后發現了這一點: 等待直到執行了多個操作-包括完成塊(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);

然后我什么也沒得到。

哪里錯了?

您可能沒有任何輸出,因為您的程序永遠不會超過對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之后—兩種方法都可以,但是有時我發現通過調用方法而不是將所有代碼放在塊中來使代碼井井有條是比較容易的。如果您想在成功和失敗塊)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM