我需要等待几个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 :(得分: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。