web-dev-qa-db-ja.com

NSURLConnection sendAsynchronousRequest:queue:completionHandler:複数のリクエストを連続して作成しますか?

私はNSURLConnection'ssendAsynchronousRequest:queue:completionHandler:すばらしい方法。しかし、今度は複数のリクエストを連続して行う必要があります。

この素晴らしい非同期メソッドを使用しながら、これをどのように行うことができますか?

53
Nic Hubbard

必要な動作に応じて、これを行う方法はたくさんあります。

一度に大量の非同期リクエストを送信し、完了したリクエストの数を追跡し、すべてが完了したら何かを行うことができます。

NSInteger outstandingRequests = [requestsArray count];
for (NSURLRequest *request in requestsArray) {
    [NSURLConnection sendAsynchronousRequest:request 
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        [self doSomethingWithData:data];
        outstandingRequests--;
        if (outstandingRequests == 0) {
            [self doSomethingElse];
        }
    }];
}

ブロックを連鎖させることができます:

NSMutableArray *dataArray = [NSMutableArray array];    
__block (^handler)(NSURLResponse *response, NSData *data, NSError *error);

NSInteger currentRequestIndex = 0;
handler = ^{
    [dataArray addObject:data];
    currentRequestIndex++;
    if (currentRequestIndex < [requestsArray count]) {
        [NSURLConnection sendAsynchronousRequest:[requestsArray objectAtIndex:currentRequestIndex] 
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:handler];
    } else {
        [self doSomethingElse];
    }
};
[NSURLConnection sendAsynchronousRequest:[requestsArray objectAtIndex:0] 
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:handler];

または、非同期ブロックですべてのリクエストを同期的に実行できます。

dispatch_queue_t callerQueue = dispatch_get_current_queue();
dispatch_queue_t downloadQueue = dispatch_queue_create("Lots of requests", NULL);
    dispatch_async(downloadQueue, ^{
        for (NSRURLRequest *request in requestsArray) {
            [dataArray addObject:[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]];
        }
        dispatch_async(callerQueue, ^{
            [self doSomethingWithDataArray:dataArray];
        });
    });
});

追伸これらのいずれかを使用する場合は、エラーチェックを追加する必要があります。

108
yuji