Порядок выполнения задачи 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
Другие вопросы по тегам