NSURLSessionDataTask的最大并发实例

时间:2019-06-23 23:01:47

标签: ios objective-c cocoa-touch

我有一个使用NSURLSessionDataTask调用API的函数,您可以在这里看到它:

- (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 :(得分:0)

我同意@Rob的意见,他可以为URLSession创建自己的配置。但是,如果此sharedSession用于不同的作业,并且他希望此作业以最多10个并发异步调用运行,我建议使用NSOperationQueuedispatch_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次调用,只要其中一种完成,其他方法将进入执行队列。

我希望这会帮助您解决您的问题。可以根据需要进行任何讨论。!!!

相关问题