Максимальное количество одновременных экземпляров NSURLSessionDataTask - PullRequest
0 голосов
/ 24 июня 2019

У меня есть функция, которая вызывает API с NSURLSessionDataTask, вы можете увидеть его здесь:

- (void)getExplorerUrl:(void (^)(NSString *))measurement_url {
    NSString *path = [NSString stringWithFormat:@"https://api.ooni.io/api/v1/measurements?report_id=%@&input=%@", self.report_id, self.url_id.url];
    NSURL *url = [NSURL URLWithString:path];
    NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (!error) {
            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
            NSArray *resultsArray = [dic objectForKey:@"results"];
            if ([resultsArray count] == 0)
                measurement_url(nil);
            measurement_url([[resultsArray objectAtIndex:0] objectForKey:@"measurement_url"]);
        }
        else {
            // Fail
            measurement_url(nil);
            NSLog(@"error : %@", error.description);
        }
    }];
    [downloadTask resume];
}

Эта функция использует обработчик завершения для возврата значения, когда асинхронный вызов завершен.

Теперь я хочу, чтобы цикл for зацикливал множество объектов и вызывал этот API для каждого объекта:

    for (Measurement *measurement in [Measurement measurementsWithJson]){
        [measurement getExplorerUrl:^(NSString *measurement_url) {
            if (measurement_url != nil){
                //Do something
                NSLog(@"%@ measurement_url %@",measurement.Id, measurement_url);
            }
            else {
                NSLog(@"%@ measurement_url null", measurement.Id);
            }
        }];
    }

Есть ли способ установить максимальное число одновременных асинхронных вызовов равным 10?А затем выполните следующий вызов, как только закончится один вызов.

1 Ответ

0 голосов
/ 24 июня 2019

Я согласен с @Rob, что он может создать свою собственную конфигурацию для URLSession.Однако, если этот sharedSession используется в разных заданиях, и он хотел, чтобы это задание выполнялось с максимальным числом одновременных асинхронных вызовов до 10, я бы предложил использовать либо NSOperationQueue, либо dispatch_semaphore для решения этой проблемы.Пожалуйста, обратитесь к приведенному ниже примеру, чтобы вкратце понять эти подходы

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 10;

for (int i = 1; i <= 30; i++) {
    [queue addOperationWithBlock:^{
        NSLog(@"[Q] %d", i);
        sleep(1);
    }];
}

или

dispatch_queue_t q = dispatch_queue_create("q.q", DISPATCH_QUEUE_CONCURRENT);
dispatch_semaphore_t s = dispatch_semaphore_create(10);
for (int i = 1; i <= 30; i++) {
    dispatch_async(q, ^{
        NSLog(@"[Q] %d", i);
        sleep(1);
        dispatch_semaphore_signal(s);
    });

}

. Вы можете наблюдать с консоли, чтобы увидеть результаты.В основном, два подхода будут выполнять максимум 10 вызовов одновременно, и пока один из них завершится, другие будут поступать в очередь выполнения.

Надеюсь, это поможет вам решить вашу проблему.Может иметь любое обсуждение по мере необходимости. !!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...