Как остановить/отменить/приостановить/возобновить задачи в очереди GCD

Как остановить/отменить/приостановить/возобновить задачи в очереди GCD

Как остановить операции очереди фона? Я хочу остановить некоторые экраны в нашем приложении. И некоторые экраны должны быть автоматически возобновлены. Итак, как пройти очередь в iOS?

Я имею в виду, что когда пользователь просматривает время приложения, мы запускаем фоновый поток в dispatch_queue_t. Но он никогда не останавливается и не возобновляется в коде. Итак, как приостановить и возобновить очередь

Ответы

Ответ 1

Чтобы приостановить очередь отправки, просто dispatch_suspend(queue) в Objective-C или Swift 2.3, или queue.suspend() в Swift 3. Это не влияет на выполнение каких-либо задач в настоящее время, а просто предотвращает запуск новых задач в этой очереди, Кроме того, вы, очевидно, только приостанавливаете созданные очереди (а не глобальные очереди, а не главную очередь).

Чтобы возобновить очередь отправки, она dispatch_resume(queue) в Objective-C или Swift 2.3 или queue.resume() в Swift 3. Там нет понятия "авто возобновление", поэтому вам просто нужно вручную возобновить его, когда это необходимо.

Чтобы передать очередь отправки, вы просто передаете объект dispatch_queue_t, который вы создали при вызове dispatch_queue_create() в Objective-C или Swift 2.3, или в Swift 3, объект DispatchQueue, который вы создаете с помощью DispatchQueue(label:).

С точки зрения отмены задач, стоящих в очереди на очереди отправки, это новая функция iOS 8, и вы вызываете dispatch_block_cancel(block) с вашим объектом dispatch_block_t в Objective-C или Swift 2.3, или item.cancel() a DispatchWorkItem в Swift 3. Это отменяет очереди/элементы в очереди, которые еще не запущены, но не останавливают те, которые уже выполняются. Если вы хотите прервать отправленный блок/элемент, вам необходимо периодически проверять dispatch_block_testcancel() в Objective-C и Swift 2.3, или item.isCancelled в Swift 3.

Отмена блоков GCD достаточно сложна, чтобы я мог ссылаться на видео WWDC 2014 Power, Performance и Diagnostics: что нового в GCD и XPC, который вводит вас в концепцию объектов блока отправки, их очереди, их отмены и т.д. Хотя это описание более старых Objective-C и Swift 2.3 API, все концепции одинаково применимы к новому API Swift 3.

Если вы хотите отменить задачи, вы также можете рассмотреть очереди операций NSOperationQueue в Objective-C или Swift 2.3, aka OperationQueue в Swift 3, так как его отменяемые операции были на некоторое время, и вы, вероятно, найдете множество примеров в Интернете. Он также поддерживает ограничение степени concurrency с помощью maxConcurrentOperationCount (тогда как с очередями отправки вы можете выбирать только между последовательными и параллельными, а управление concurrency больше, чем требует от вас немного усилий).

При использовании очередей операций вы приостанавливаете и возобновляете, изменяя свойство suspended очереди. И чтобы передать это, вы просто передаете объект NSOperationQueue, который вы создали.


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


В ваших комментариях вы упомянули, что используете NSTimer, aka Timer в Swift 3. Если вы хотите остановить таймер, вызовите timer.invalidate(), чтобы остановить его. Создайте новый NSTimer, если вы хотите снова запустить его.

Или, если таймер действительно работает в фоновом потоке, таймеры GCD делают это гораздо более изящно, избегая глупости необходимости создания runloop на фоновом потоке, который вам нужно запустить NSTimer в фоновом потоке. С помощью таймера GCD вы можете приостановить/возобновить его, как если бы вы приостановили/возобновили очередь, просто используя объект таймера вместо объекта очереди.

Ответ 2

Вы не можете приостановить/отменить при использовании очереди GCD. Если вам нужна эта функциональность (и во многих общих случаях, даже если вы этого не сделаете), вы должны использовать API более высокого уровня - NSOperationQueue. Это построено поверх GCD, но оно дает вам возможность контролировать, сколько вещей выполняется одновременно, приостанавливать обработку очереди и отменять отдельные/все операции.