我的场景是这样的,首先我有一个服务器json api,它返回指定页面的一些数据,api就像/data/page/1
。对于这种情况,假设响应数据是:
page 1 => ['a','b']
page 2 => ['c','d']
page 3 => ['e','f']
我使用AFNetworking 2从api获取数据,对于单页数据请求它运行良好。
问题是现在我想为多个页面实现并行请求。我需要一个api用于接受一个页码的视图控制器,并回收所有这些页面的数据。我需要的是:
typedef void (^DataBlock)(id data);
- (void) dataForPages:(NSInteger)pages withSuccessBlock:(DataBlock)block;
如果视图控制器为3
参数传递pages
,我希望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
。
任何人都知道如何使用NSOperation
或GCD
处理此问题?
答案 0 :(得分:0)
经过一些代码研究后,我发现很难通过NSOperation
和NSOperationQueue
获得我想要的内容,因为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);
});