【问题标题】:how to use AFNetworking with parallel request and collect all result如何将 AFNetworking 与并行请求一起使用并收集所有结果
【发布时间】:2016-07-07 12:28:13
【问题描述】:

我的场景是这样的,首先我有一个服务器 json api,它返回一些数据用于指定页面,api 就像/data/page/1。对于这种情况,假设响应数据是:

page 1 => ['a','b']
page 2 => ['c','d']
page 3 => ['e','f']

我使用 AFNetworking 2 从 api 获取数据,对于单页数据请求它运行良好。

现在的问题是我想为多个页面实现并行请求。我需要一个用于视图控制器的 api,它接受一个页码,并用收集到的这些页面的所有数据进行回调。我需要的api是:

typedef void (^DataBlock)(id data);

- (void) dataForPages:(NSInteger)pages withSuccessBlock:(DataBlock)block;

如果视图控制器为pages参数传递3,我希望AFNetworking可以并行请求数据,然后收集3个结果然后在回调块中使用。

我尝试使用NSOperationQueue处理多个AFHTTPRequestOperation但失败,代码演示是这样的:

- (void) dataForPages:(NSInteger)pages withSuccessBlock:(DataBlock)block
{

    //want to use for each, here suppose pages is 3

    NSMutableArray *result = [[NSMutableArray alloc] init];

    AFHTTPRequestOperation  *op1 = [[AFHTTPRequestOperation alloc] initWithRequest:@"/data/page/1"];
    AFHTTPRequestOperation  *op2 = [[AFHTTPRequestOperation alloc] initWithRequest:@"/data/page/2"];
    AFHTTPRequestOperation  *op3 = [[AFHTTPRequestOperation alloc] initWithRequest:@"/data/page/3"];


    [op1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        [result addObjectsFromArray: responseObject];    //responseObject is ['a', 'b']
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];

    [op2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        [result addObjectsFromArray: responseObject];    //responseObject is ['c', 'd']
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];

    [op3 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        [result addObjectsFromArray: responseObject];    //responseObject is ['e', 'f']
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];


    NSOperationQueue *q = [[NSOperationQueue alloc] init];

    [q addOperation:op1];
    [q addOperation:op2];
    [q addOperation:op3];


    [q waitUntilAllOperationsAreFinished];


    block(result);
}

在我的测试中结果总是空的,我不太明白waitUntilAllOperationsAreFinished

有人知道如何用NSOperationGCD 处理这个问题吗?

【问题讨论】:

    标签: ios objective-c afnetworking


    【解决方案1】:

    经过一些代码研究,我发现使用NSOperationNSOperationQueue 很难得到我想要的,因为AFNetworking 有它自己的completion block handler

    最终的解决方案是使用dispatch_group,所有代码都是这样的:

    dispatch_group_t group = dispatch_group_create();
    
    
    NSURLRequest *req1 = ...;
    NSURLRequest *req2 = ...;
    
    AFHTTPRequestOperation  *op1 = [[AFHTTPRequestOperation alloc] initWithRequest:req1];
    AFHTTPRequestOperation *op2 = [[AFHTTPRequestOperation alloc] initWithRequest:req2];
    
    NSMutableArray *result = [[NSMutableArray alloc] init];
    
    dispatch_group_enter(group);     //enter group
    
    [op1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        [result addObjectsFromArray: responseObject];
        dispatch_group_leave(group);      //leave group in completion handler
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        dispatch_group_leave(group);
    }];
    
    dispatch_group_enter(group);
    [op2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        [result addObjectsFromArray: responseObject];
        dispatch_group_leave(group);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        dispatch_group_leave(group);
    }];
    
    [op1 start];
    [op2 start];
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        block(result);
    });
    

    【讨论】:

      猜你喜欢
      • 2015-02-15
      • 2019-12-20
      • 1970-01-01
      • 2012-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多