Порядок выполнения задачи NSURLSession

Я добавляю несколько задач в NSURLSession (фоновый режим) по порядку. Я сохранил HTTPMaximumConnectionsPerHost = 1. Однако я вижу, что загрузки выполняются в случайном порядке, то есть после того, как 1-й элемент может быть выбран 5-й элемент, а затем 3-й элемент и т. д. - загрузка не происходит в порядке Я предоставил NSURLSession. Есть ли способ заказать загрузку именно так, как она добавлена?


person tuttu47    schedule 19.10.2015    source источник
comment
вы должны вызвать следующий элемент после завершения последнего элемента, пожалуйста, покажите свой код   -  person Mo Farhand    schedule 19.10.2015
comment
Я пробовал цепочку загрузок. Но когда первый элемент завершает работу и планирует вторую загрузку в фоновом режиме, он начинает загружаться, а затем резко останавливается. Второй элемент не загружается в фоновом режиме.   -  person tuttu47    schedule 21.10.2015


Ответы (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
person HSG    schedule 19.10.2015
comment
Я попытался с NSOperationQueue, и в режиме фоновой загрузки это стало очень грязно. Как упоминалось здесь: stackoverflow.com /questions/21918722/, я не думаю, что это легко и практично. Я также пробовал цепочку загрузок, но она резко останавливается со вторым элементом (примерно через 30 секунд, когда ОС приостанавливает ваше приложение при фоновом пробуждении). - person tuttu47; 22.10.2015
comment
@tuttu47 tuttu47 Не могли бы вы опубликовать здесь свой код, чтобы мы могли легко выяснить проблему. - person HSG; 23.10.2015
comment
Я добавил подробное описание с кодом здесь: stackoverflow.com/questions/ 33285179/ - person tuttu47; 24.10.2015