ios - NSURLSessionDataTask 的最大并发实例数
问题描述
我有一个调用 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?然后在一个呼叫完成后立即执行下一个呼叫。
解决方案
我同意@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 个调用,只要一个完成,其他的就会进入执行队列。
我希望这将帮助您解决您的问题。有需要可以讨论哦!!!
推荐阅读
- typescript - 商店状态类型不适用于模块
- r - 如何在 R Markdown 的两个单独的标题下插入两个单独的书目(不在正文中引用它们)?
- python - Discord Bot 计算“bruh”被说了多少次
- mysql - 无法通过使用表的 select 语句将行插入到表中
- reactjs - redux next wrapper - hydrate 方法在页面更改时失去了先前的状态
- javascript - 删除部分字符串/url查询参数的Javascript
- swift - 我如何在关闭视图控制器的同时切换到另一个视图控制器
- reactjs - 如何根据工具提示内容设置材质ui工具提示的高度
- reactjs - 以下几种初始化状态的方式有什么区别
- javascript - 从字符串中提取给定数量标识符的键,并使用 Javascript 中的正则表达式形成哈希映射/对象