Для чего используется DispatchGroup в Grand Central Dispatch (GCD)?

«Для чего используется DispatchGroup в Grand Central Dispatch (GCD)?» — вопрос из категории Многопоточность, который задают на 31% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

DispatchGroup — это механизм GCD для синхронизации группы асинхронных или параллельных задач. Он позволяет отслеживать завершение произвольного количества задач и выполнить финальный блок кода, когда все они будут закончены.

Основные методы:

  • enter(): Увеличивает внутренний счетчик группы (начало задачи).
  • leave(): Уменьшает счетчик (завершение задачи).
  • notify(queue:execute:): Запланировать блок кода, который выполнится, когда счетчик станет равен нулю.
  • wait(): Синхронно блокирует текущий поток до завершения всех задач группы (использовать с осторожностью).

Типичный use case: Загрузка данных из нескольких источников.

let imageGroup = DispatchGroup()
var downloadedImages: [UIImage] = []

// Задача 1: Загрузка аватара
imageGroup.enter()
networkService.loadAvatar { image in
    downloadedImages.append(image)
    imageGroup.leave()
}

// Задача 2: Загрузка обложки
imageGroup.enter()
networkService.loadCover { image in
    downloadedImages.append(image)
    imageGroup.leave()
}

// Действие после завершения ВСЕХ загрузок
imageGroup.notify(queue: .main) {
    // Все изображения загружены, счетчик = 0
    self.updateUI(with: downloadedImages)
    print("Все изображения готовы")
}
// Основной поток не блокируется.

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

  • Каждый enter() должен быть сбалансирован соответствующим leave().
  • notify() — это асинхронный метод, он не блокирует вызывающий поток.
  • Идеально подходит для агрегации результатов нескольких независимых асинхронных операций.