等待多个AFNetworking请求完成

时间:2016-04-24 13:59:09

标签: objective-c afnetworking grand-central-dispatch

我需要等待几个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上卡住了,因为既没有调用成功块,也没有调用失败块。

我该如何解决?

4 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分: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将被调用。

答案 2 :(得分: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
    });

答案 3 :(得分: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;
      }
    }];
}

这将阻止主线程,直到完成设置为YES。