Порядок выполнения задачи NSURLSession
Я добавляю несколько задач в NSURLSession (фоновый режим) по порядку. Я сохранил HTTPMaximumConnectionsPerHost = 1. Тем не менее, я вижу, что загрузки выполняются в случайном порядке, т. Е. После того, как 1-й элемент может быть выбран 5-й элемент, а затем 3-й элемент и т. Д. - загрузка не происходит в порядке Я предоставил NSURLSession. Есть ли способ заказать загрузку в точности так, как она добавлена?
1 ответ
Мы не гарантируем, что ваши задачи будут выполнены в порядке с настройкой HTTPMaximumConnectionsPerHost = 1
потому что это просто гарантирует выполнение одной задачи за раз. С точки зрения выполнения задач синхронно по порядку, вы можете использовать NSOperationQueue и NSOperation для добавления зависимости между операциями.
NSMutableArray *operations = [NSMutableArray array];
NSArray *urls = @[];
NSURLSession *urlSession = [NSURLSession sharedSession];
for (int i = 0;i < urls.count;i++) {
NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSURLSessionDataTask *task = [urlSession dataTaskWithURL:[NSURL URLWithString:urls[i]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
[task resume];
}];
i > 0 ? [operation addDependency:operations[i - 1]] : 0;
[operations addObject:operation];
}
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
[queue addOperations:operations waitUntilFinished:YES];
Другое решение - использовать семафор диспетчеризации GCD.
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSArray *urls = @[];
NSURLSession *urlSession = [NSURLSession sharedSession];
for (NSString *url in urls) {
NSURLSessionDataTask *task = [urlSession dataTaskWithURL:[NSURL URLWithString:url] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_semaphore_signal(semaphore); // signal when done
}];
[task resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // wait for signal before continuing
}
//Do s.t after all tasks finished