我有一个使用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?一个通话结束后立即执行下一个通话。
答案 0 :(得分:0)
我同意@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次调用,只要其中一种完成,其他方法将进入执行队列。
我希望这会帮助您解决您的问题。可以根据需要进行任何讨论。!!!