Как в GCD дождаться завершения нескольких асинхронных задач?

«Как в GCD дождаться завершения нескольких асинхронных задач?» — вопрос из категории Многопоточность, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, для этого используется DispatchGroup. Он позволяет отслеживать завершение группы задач и выполнить код, когда все они будут выполнены.

Основные шаги:

  1. Создать группу: DispatchGroup()
  2. Войти в группу перед каждой задачей: enter()
  3. Выйти из группы после завершения каждой задачи: leave()
  4. Установить обработчик завершения: notify() или синхронно дождаться: wait()

Пример с асинхронным уведомлением:

let group = DispatchGroup()

// Задача 1
group.enter()
networkService.fetchData { result in
    defer { group.leave() } // Гарантирует выход
    // Обработка результата
}

// Задача 2
group.enter()
databaseService.loadData { result in
    defer { group.leave() }
    // Обработка результата
}

// Действие после всех задач
group.notify(queue: .main) {
    print("Все асинхронные задачи завершены")
    // Обновление UI или продолжение логики
}

Важные моменты:

  • Количество вызовов enter() должно строго соответствовать количеству leave()
  • Используйте defer { group.leave() } для гарантированного выхода
  • Метод wait() блокирует текущий поток — используйте осторожно
  • Для работы с wait() в main thread используйте .async