複数の操作(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];
もちろん、リクエストは非同期であるため、これは期待どおりには機能しません。 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は、GCDから抽象化したこの種の操作のための方法を設計しました。
-enqueueBatchOfHTTPRequestOperationsWithRequests:progressBlock:completionBlock:
-enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:
[〜#〜] faq [〜#〜] をご覧ください
私はこのような何かを信じています:
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];
私の要件は、文字列(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個の非同期呼び出しではなく、カスケードで呼び出しが行われます。