等到多个networking请求全部执行 – 包括它们的完成块

我有多个操作(他们是AFNetworking请求)与完成块需要一些时间来执行,并需要在所有请求的末尾保存一个核心数据对象。

MyCoreDataObject *coreDataObject; AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute1 = responseObject; sleep(5); }]; [operation1 start]; AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute2 = responseObject; sleep(10); }]; [operation1 operation2]; [context save:nil]; 

当然,这不符合我的要求,因为请求是asynchronous的。 我试图像这样添加一个NSOperationQueue:

 NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init]; [operationQueue setMaxConcurrentOperationCount:2]; AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute1 = responseObject; sleep(5); }]; [operationQueue addOperation:operation1]; AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute2 = responseObject; sleep(10); }]; [operationQueue addOperation:operation2]; [imageQueue waitUntilAllOperationsAreFinished]; [context save:nil]; 

这看起来好一点。 使用waitUntilAllOperationsAreFinished ,我的队列阻塞当前的线程,直到我的请求完成,但直到我的成功块完成,这是我真正需要的。

任何想法如何实现这个好方法?

使用派遣组。

 dispatch_group_t group = dispatch_group_create(); MyCoreDataObject *coreDataObject; dispatch_group_enter(group); AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute1 = responseObject; sleep(5); dispatch_group_leave(group); }]; [operation1 start]; dispatch_group_enter(group); AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute2 = responseObject; sleep(10); dispatch_group_leave(group); }]; [operation2 start]; dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_release(group); [context save:nil]; 

AFNetworking为此类操作devise了一个方法,从GCD中抽象出来:

-enqueueBatchOfHTTPRequestOperationsWithRequests:progressBlock:completionBlock:

-enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:

看看常见问题

我相信这样的事情:

 NSMutableArray *mutableOperations = [NSMutableArray array]; for (NSURL *fileURL in filesToUpload) { NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { [formData appendPartWithFileURL:fileURL name:@"images[]" error:nil]; }]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; [mutableOperations addObject:operation]; } NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[...] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) { NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations); } completionBlock:^(NSArray *operations) { NSLog(@"All operations in batch complete"); }]; [[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO]; 

参考文档: http : //cocoadocs.org/docsets/AFNetworking/2.5.0/

我的要求是从string(URL)数组做很多请求,

 func updateSourceData(element: Int) { if element > availableUrls.count - 1 { return } let service = SourceDataServiceDao() let currentUrl = availableUrls[element] service.fooCall(url: currentUrl, completion: { (response, error) -> Void in self.updateSourceData(element + 1) }) } 

显然,通过这种方式调用级联,而不是N个asynchronous调用。