web-dev-qa-db-fra.com

NSURLConnection sendAsynchronousRequest: queue: d'achèvementHandler: faire plusieurs demandes d'affilée?

J'utilise NSURLConnection'ssendAsynchronousRequest:queue:completionHandler: méthode qui est super. Mais, je dois maintenant faire plusieurs demandes d'affilée.

Comment puis-je le faire tout en utilisant cette excellente méthode asychrone?

53
Nic Hubbard

Il existe de nombreuses façons de procéder en fonction du comportement souhaité.

Vous pouvez envoyer un tas de demandes asynchrones à la fois, suivre le nombre de demandes qui ont été terminées et faire quelque chose une fois qu'elles sont toutes terminées:

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];
        }
    }];
}

Vous pouvez enchaîner les blocs ensemble:

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];

Ou vous pouvez faire toutes les demandes de manière synchrone dans un bloc ansynchrone:

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];
        });
    });
});

P.S. Si vous utilisez l'un de ces éléments, vous devez ajouter une vérification des erreurs.

108
yuji