Имам n задачи, изпращащи към сървър. Когато ги стартирам от [taskN resume]
, те ще стартират паралелно, но искам да ги стартирам последователно - ако първата задача приключи, ще се стартира друга задача. Някакви предположения?
Няколко задачи за изтегляне последователно
Отговори (2)
За това е най-добре да използвате NSOperation
и NSOperationQueue
.
Той управлява опашка от задачи и всяка от тях се изпълнява във фонова нишка.
Като настроите опашката да има само 1 едновременна операция, тя ще ги постави на опашка, както искате.
Ти трябва...
Създайте
NSOperation
подклас, който извършва вашето изтегляне. Направете го да извършва СИНХРОННИ изтегляния. Не е необходимо да са асинхронни, тъй като вече ще бъдат във фонова нишка.Настройте
NSOperationQueue
и задайтеmaximumNumberOfConcurrentOperations
на 1.Добавете вашите операции към опашката.
Това е най-лесният начин да се обърнете към NSOperationQueue
, но има много повече неща, които можете да правите с него.
Има и няколко въпроса и уроци за това, така че няма да навлизам в пълни подробности тук, тъй като би трябвало да можете да намерите други SO въпроси.
Дойдох с доста просто решение без подкласове:
проба:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];
// first download task
[queue addOperationWithBlock:^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); // create a semaphore
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionTask *task1 = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_semaphore_signal(semaphore); // go to another task
}];
[task1 resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // wait to finish downloading
}];
// second download task
[queue addOperationWithBlock:^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionTask *task2 = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_semaphore_signal(semaphore);
}];
[task2 resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}];
Тези две операции (задача1, задача2) ще се изпълнят последователно, така че ще изчакат, докато операцията n-1 приключи.
Използване на семафори, вдъхновени от NSURLSession с NSBlockOperation и опашки