Ответ
GCD не предоставляет прямого механизма отмены уже запущенной задачи, но есть несколько обходных решений:
1. DispatchWorkItem (отмена до выполнения)
let workItem = DispatchWorkItem {
print("Эта задача может быть отменена")
}
// Запланировать выполнение
DispatchQueue.global().asyncAfter(deadline: .now() + 0.5, execute: workItem)
// Отменить до начала выполнения
workItem.cancel()
2. Флаг отмены для выполняющихся задач
class CancellableTask {
private var isCancelled = false
private let queue = DispatchQueue(label: "com.example.task", attributes: .concurrent)
func start() {
queue.async { [weak self] in
guard let self = self else { return }
for i in 1...100 {
// Периодическая проверка флага
if self.isCancelled {
print("Задача отменена на шаге (i)")
return
}
// Полезная работа
Thread.sleep(forTimeInterval: 0.1)
}
}
}
func cancel() {
queue.async(flags: .barrier) {
self.isCancelled = true
}
}
}
3. OperationQueue (предпочтительный способ)
let operationQueue = OperationQueue()
let operation = BlockOperation {
// Длительная операция
}
operationQueue.addOperation(operation)
// Отмена операции
operation.cancel()
Рекомендации:
- Для сложных сценариев используйте
OperationQueueс поддержкой зависимостей и отмены - В современных Swift проектах предпочитайте
async/awaitсTaskиTask.checkCancellation() - Всегда реализуйте периодическую проверку флагов отмены в длительных операциях