убивать элементы в очереди dispatch_async в iOS - PullRequest
10 голосов
/ 03 марта 2012

Я запускаю кучу элементов в фоновом режиме, используя dispatch_async, и иногда я хочу убить то, что у меня в очереди - возможно ли это? Например, этот код запускается в представлении, а затем пользователь возвращается на экран. Все эти запущенные действия продолжают выполняться независимо от обратной навигации. В идеале я хотел бы убить этих предметов из бега:

dispatch_async(dispatch_get_global_queue(2, 0), ^{
        for (int i=0; i<[self.manufacturers count]; i++) {
            NSString *manufacturerID = [[[self.manufacturers objectAtIndex:i] ManufacturerID] stringValue];
            [self doSync:manufacturerID withIndex:i setTimer:YES];
        }
    });

Если я создаю очередь и называю ее именем, а затем освобождаю ее в dealloc представления, для которого она вызывается, они все еще продолжают работать.

Ответы [ 2 ]

14 голосов
/ 03 марта 2012

Нет явного предоставления в очереди отправки для завершения.Для этого достаточно проверить место эвакуации, чтобы определить завершение.По сути, это был бы семафор.

NSOperationQueue (абстракция более высокого уровня, но все же сборка с использованием GCD внизу) действительно поддерживает отмену операций.Так, например, вы можете создать серию NSOperations и добавить их в NSOperationQueue, а затем отправить сообщение -cancelAllOperations в очередь, когда вам не нужно его завершать.

Большая часть выбранной вами архитектурыбудет зависеть от того, сколько из них работает и имеют ли они разные триггеры.Среди реализаций NSOperation, вероятно, является «самым чистым» решением, поскольку у вас есть произвольная очередь, в которой вы можете наблюдать за завершением операций, а также вы можете отменить невыполненные операции.Вниз по шкале взлома будет изменчивое местоположение, которое каждый из этих блоков будет наблюдать внутри узкой петли, чтобы определить, не собираются ли они закончить преждевременно.Еще дальше будет глобальная переменная для той же базовой функции.

В конце концов, даже реализация NSOperation включает тест для выхода в согласованном месте (поскольку простое уничтожение потока может привести к несогласованностив данных, которые используются или в распределениях / переобучениях).

2 голосов
/ 04 марта 2012

Лучший способ сделать это - создать собственную параллельную очередь (не использовать одну из глобальных), а затем вызвать dispatch_suspend () для очереди, когда вы хотите прекратить обработку в ней. В этот момент прочтите это: Очереди рассылки: как определить, запущены ли они и как их остановить

Использование флага отмены позволит вам затем возобновить очередь таким образом, чтобы все оставшиеся блоки в основном просто выходили (после выполнения любого необходимого им управления памятью, например, освобождения ресурсов), когда вы возобновляете его снова. Вы также можете сразу отправить dispatch_release () в очередь после ее возобновления.

...