Как отменить задачу, отправленную в очередь GCD?

GCD (Grand Central Dispatch) — системный API, предназначенный для управления потоками в iOS/macOS. После добавления задачи (block) в очередь нельзя отменить её напрямую. Для реализации отмены используют специальные…

Короткий ответ

Что ответить на собеседовании

GCD (Grand Central Dispatch) — системный API, предназначенный для управления потоками в iOS/macOS. После добавления задачи (block) в очередь нельзя отменить её напрямую. Для реализации отмены используют специальные обертки, например DispatchWorkItem. Нужно создать DispatchWorkItem, передать его в очередь, а для отмены вызвать .cancel(). Вызов cancel лишь изменяет внутреннее состояние объекта, поэтому задача должна самостоятельно проверять isCancelled и реагировать на это. Такой подход эффективен для отложенных или повторяющихся операций, но не гарантирует остановку уже выполняющейся задачи. На практике ссылку на DispatchWorkItem сохраняют,…

Подробный разбор

Ответ с пояснениями

Как отменить задачу, отправленную в очередь GCD?

  • GCD (Grand Central Dispatch) — системный API, предназначенный для управления потоками в iOS/macOS.
  • После добавления задачи (block) в очередь нельзя отменить её напрямую.
  • Для реализации отмены используют специальные обертки, например DispatchWorkItem.
  • Нужно создать DispatchWorkItem, передать его в очередь, а для отмены вызвать .cancel().
  • Вызов cancel лишь изменяет внутреннее состояние объекта, поэтому задача должна самостоятельно проверять isCancelled и реагировать на это.
  • Такой подход эффективен для отложенных или повторяющихся операций, но не гарантирует остановку уже выполняющейся задачи.
  • На практике ссылку на DispatchWorkItem сохраняют, а при необходимости вызывают у него cancel.

Итак, для отмены задачи GCD применяют DispatchWorkItem, а внутри кода задачи проверяют isCancelled.

Подробный ответ

Основной ответ

В Grand Central Dispatch (GCD) отсутствует прямой способ отменить задачу — обычно это блок кода, уже переданный в очередь. Поскольку асинхронная задача может начать выполняться в любой момент, поддержку отмены необходимо закладывать в её собственную логику. Как правило, используют проверку флага отмены внутри блока или более специализированный вариант — DispatchWorkItem, для которого отмена выполняется методом cancel().

Ключевые моменты

  • DispatchWorkItem служит контейнером для блока кода: у него можно вызвать cancel(), а непосредственно внутри DispatchWorkItem следует проверить isCancelled и при необходимости завершить работу.
  • Когда задача уже запущена или вот-вот начнёт выполняться, отмена только изменяет состояние isCancelled и не прерывает выполнение на низком уровне. Поэтому фактическую остановку следует обрабатывать в коде самой задачи.
  • В более сложных случаях используют собственные схемы отмены — например, атомарные булевые переменные-флаги, значения которых проверяются в цикле или на отдельных ключевых этапах работы.

Практический контекст

Распространённый шаблон следующий: создаём DispatchWorkItem, передаём его в очередь, а затем в нужный момент вызываем workItem.cancel(). Внутри блока размещают:

let workItem = DispatchWorkItem {
for i in 0..<100 {
if workItem.isCancelled { return }
// Работаем с i
}
}
DispatchQueue.global().async(execute: workItem)

// Позже
workItem.cancel()

Благодаря этому отмену асинхронных задач GCD можно реализовать с минимальными усилиями. Такой подход широко применяется в проектах iOS/Swift с GCD начиная с iOS 8+, где DispatchWorkItem поддерживается стабильно.

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку