2016-06-22 3 views
0

Я хочу выполнить несколько сетевых методов с использованием NSOperation для каждого из них и добавить операции в NSOperationQueue, который установлен на обратный поток, я хочу, чтобы NSOperations сериализовался.Как использовать NSOperationQueue и NSOperation для периодического вызова сериализованных задач загрузки с использованием NSTimer на фоне Thread

Вызов, который создает очередь NSOperation, вызывается периодически, каждые 30 секунд, используя NSTimer.

Вот код пропущено до сих пор:

NSTimer *timer; 
NSOperationQueue *bgQueue; 

- (void)startdDownloadLoop{ 

    if (![self.timer isValid]){ 

     self.bgQueue = [[NSOperationQueue alloc] init]; 
     self.timer = [NSTimer scheduledTimerWithTimeInterval:30.0 
                 target:self 
                selector:@selector(updateDB) 
                userInfo:nil 
                repeats:YES]; 

    } 

} 

- (void)updateDB{ 

    //  Next code was removed since si similar to the call `[self.bgQueue cancelAllOperations];`, as @robinkunde suggested 
    //  for (NSOperation *operation in [self.bgQueue operations]) { 
    //   if (operation.isExecuting) { 
    //    [operation cancel]; 
    //   } 
    //  } 

    [self.bgQueue cancelAllOperations]; 


    self.bgQueue = [[NSOperationQueue alloc] init]; 
    self.bgQueue.maxConcurrentOperationCount = 1; 

    NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{ 
     [NetworkManager downloadCars]; 
    }]; 

    NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{ 
     [NetworkManager downloadPartsForAllCars]; 
    }]; 

    NSBlockOperation *blockOp3 = [NSBlockOperation blockOperationWithBlock:^{ 
     [NetworkManager downloadEachPathSpecs]; 
    }]; 

    [self.bgQueue addOperation:blockOp1]; 
    [self.bgQueue addOperation:blockOp2]; 
    [self.bgQueue addOperation:blockOp3]; 

} 

В NetworkManager методы POST/GET методы обработчиком завершения, что после того, как они заканчивают загрузку, они сохраняют дату в БД, а затем обновить пользовательский интерфейс с помощью уведомление.

Update:

С замешательством, я думал после моего актуального вопроса относительно кода как залежи:

1- Если выполнение NSOperationQueue будет серийным?

2 - если при вызове [operation cancel] прекратится выполнение операции?

3 - Если при вызове cancelAllOperations и повторной инициализации I это правильный способ очистки текущего NSOperationQueue?

+0

Это, вероятно, не будет делать то, что вы хотите. Предположительно каждый из методов 'download ...' выполняется асинхронно. Если это так, как только будет отправлена ​​сетевая операция, блок завершится, и следующий представленный блок начнет выполняться, даже если первая операция загрузки еще не завершена. Вам, вероятно, будет лучше использовать dispatch_group или даже лучше толковать уведомления, а не опросить, что является дорогостоящим с точки зрения аккумулятора и сетевого трафика. – Paulw11

+0

Что касается операций отмены, то каждый блок проверяет блоки «isCancelled» и прекратите работу, если это необходимо.Операционная очередь не может фактически отменить операцию, она просто устанавливает свойство для указания операции, которую она должна отменить. См. Http://stackoverflow.com/questions/8113268/how-to-cancel-nsblockoperation – Paulw11

ответ

1

1) Вы можете установить свойство maxConcurrentOperationCount в очереди на 1, чтобы обеспечить последовательное выполнение.

2) Это только устанавливает свойство isCancelled на операцию. Необходимо действовать с этим изменением и переместиться в готовое состояние, чтобы его можно было удалить из очереди.

Как для вашего конкретного примера: NSBlockOperation считается законченным, когда все прикрепленные блоки возвращены. Это фактически означает, что, если вызовы NetworkManager не синхронны, блок немедленно возвращается, операция считается завершенной, и очередь запускает следующую операцию. Вполне возможно, что очередь заканчивается до завершения первой сетевой операции. Если вы хотите выполнить их по одному, это не способ сделать это.

Вы можете использовать синхронные сетевые операции, но это все равно не позволит вам их отменить.

Заканчивать этот ответ: NSURLSession with NSBlockOperation and queues

3) Это связано с 2). Все cancelAllOperations делает это свойство isCancelled на всех операциях. Пока эта операция не будет завершена, очередь будет продолжать существовать. Создание новой очереди на одно и то же свойство не меняет этого.

+0

Спасибо @robinkunde за ваш быстрый ответ. Я поменяю свой код соответствующим образом, удалив дополнительный цикл for, но, тогда мой вопрос заключается в том, как можно Я заставляю остановить NSOperation, который все еще работает? –

+0

Я обновил свой ответ. – robinkunde