2016-04-24 7 views
5

AFNetworking要求が完了するまで待つ必要があります。ディスパッチグループを使用しようとしましたが、正しく取得できないようです。ここで複数のAFNetworking要求が完了するまで待ちます

は私のコードです:

dispatch_group_t group = dispatch_group_create(); 

for (int k = 0; k < 10 ; k++) { 
    dispatch_group_enter(group); 

    [[AFHTTPSessionManager manager] GET:@"http://google.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
     NSLog(@"success"); 
     dispatch_group_leave(group); 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"failure"); 
     dispatch_group_leave(group); 
    }]; 
} 

dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

NSLog(@"DONE"); 

問題はどちらも成功ブロックするので、それは、dispatch_group_waitにはまり、また故障ブロックが呼び出されるということです。

どうすれば解決できますか?

+0

dispatch_group_notifyを使用してみましたか? – jtbandes

+0

はい、それは動作します。しかし、それは私の問題を解決しません。アプリケーションがどのようにビルドされたか(プロジェクトを継承したため)、私はこのメソッドの実行を停止する必要があります。 – guidev

+0

これは残念です。それをリファクタリングすることを検討したいかもしれません。スレッドをブロックすると、別のスレッドが何かをするのを待つだけの仕事をしているスレッドを浪費します。 libdispatchは、サービス待ち行列のために起動する64スレッドの制限を課しているので、あなたのアプリケーションが何をしているかに応じて問題になる可能性があります。 – jtbandes

答えて

6

completionBlockのディスパッチキュー。 NULL(デフォルト)の場合、メインキューが使用されます。

dispatch_group_t group = dispatch_group_create(); 

dispatch_queue_t queue = dispatch_queue_create("com.app", DISPATCH_QUEUE_CONCURRENT); 

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
manager.completionQueue = queue; 
for(int k = 0; k < 10; k++) { 
    dispatch_group_enter(group); 

    dispatch_async(queue, ^{ 
     NSLog(@"%d", k); 
     [manager GET:@"http://baidu.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) { 
      NSLog(@"success"); 
      dispatch_group_leave(group); 
     } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) { 
      NSLog(@"failure"); 
      dispatch_group_leave(group); 
     }]; 
    }); 
} 

dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

NSLog(@"DONE"); 
0

は、すべてのタスクが完了することになるとき

dispatch_group_t group = dispatch_group_create(); 

for (int k = 0; k < 10 ; k++) { 
    dispatch_group_enter(group); 

    [[AFHTTPSessionManager manager] GET:@"http://google.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
     NSLog(@"success"); 
     dispatch_group_leave(group); 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"failure"); 
     dispatch_group_leave(group); 
    }]; 
} 

dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 

    NSLog(@"All done"); 

}); 

dispatch_group_notifyが呼び出されます、これを試してみてください。

0

PromiseKit。非常に強力です。

シーケンシャル

 [self.manager GET:@"http://www.error-url.ss/" parameters:nil].then(^(id responseObject, AFHTTPRequestOperation *operation){ 
     NSLog(@"first request completed for operation: %@", operation.request.description); 
     return [self.manager GET:@"http://www.apple.com" parameters:nil]; 
    }).then(^{ 
     NSLog(@"second request completed"); 
    }).catch(^(NSError *error){ 
     NSLog(@"error happened: %@", error.localizedDescription); 
     NSLog(@"original operation: %@", error.userInfo[AFHTTPRequestOperationErrorKey]); 
    }); 

OR(あなたの要件ごと)

 [PMKPromise when:@[ 
         [self.operationManager GET:@"ip" parameters:nil].then(^(){numberOfOperationsCompleted ++;}), 
         [self.operationManager GET:@"get" parameters:nil].then(^(){numberOfOperationsCompleted ++;}) 
         ]].then(^(){ 
     //do something when all operations are finished 
    }); 
0

このヘルパー機能を使用して、メインスレッドをブロックできます。

static inline void hxRunInMainLoop(void(^block)(BOOL *done)) { 
__block BOOL done = NO; 
block(&done); 
while (!done) { 
    [[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow:.1]]; 
} 
} 

また、カウンタを実装して、成功または失敗したときにカウンタを増やす必要があります。

- (void)test { 
    __block int count = 0; 

    hxRunInMainLoop(^(BOOL *done) { 

    for (int i = 0; i < 10; i++) { 

    [AFHTTPSessionManager manager] GET:@"http://google.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
     NSLog(@"success"); 
     count++; 
     if (count == 9) { 
     *done = YES; 
     } 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"failure"); 
     count++; 
     if (count == 9) { 
     *done = YES; 
     } 
    }]; 
} 

これは、doneがYESに設定されるまでメインスレッドをブロックします。

関連する問題