Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: DispatchGroup, async, URLSession, iOS, concurrency

Как реализовать загрузку массива изображений по URL с использованием DispatchGroup?

Этот вопрос проверяет умение управлять параллельными асинхронными задачами в iOS-разработке, используя DispatchGroup для синхронизации загрузки нескольких изображений.

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

DispatchGroup позволяет отслеживать завершение группы асинхронных задач. Создайте группу с помощью DispatchGroup(), перед каждой загрузкой вызывайте group.enter(), а после завершения (успеха или ошибки) — group.leave(). Используйте group.notify(queue:) для выполнения кода после загрузки всех изображений. Это гарантирует, что вы получите уведомление, когда все задачи завершатся, даже если они выполняются в разных очередях.

Длинный ответ

В iOS-разработке часто возникает необходимость загрузить несколько изображений по разным URL и обработать их все вместе после завершения всех загрузок. DispatchGroup — это механизм GCD (Grand Central Dispatch), который позволяет синхронизировать выполнение группы задач.

Как работает DispatchGroup

DispatchGroup отслеживает количество "входов" и "выходов". Каждая асинхронная задача должна сообщить группе о своём начале (вызовом enter()) и завершении (вызовом leave()). Когда количество вызовов leave() сравняется с количеством enter(), группа считается завершённой.

Практическая реализация

Вот пример функции, которая загружает массив изображений:

func loadImages(from urls: [URL], completion: @escaping ([UIImage?]) -> Void) {
    let group = DispatchGroup()
    var images: [UIImage?] = Array(repeating: nil, count: urls.count)
    
    for (index, url) in urls.enumerated() {
        group.enter()
        URLSession.shared.dataTask(with: url) { data, _, error in
            defer { group.leave() } // Гарантирует вызов leave() даже при ошибке
            
            if let data = data, error == nil {
                images[index] = UIImage(data: data)
            }
        }.resume()
    }
    
    group.notify(queue: .main) {
        completion(images)
    }
}

Ключевые моменты реализации

  • Используйте defer { group.leave() } внутри замыкания задачи, чтобы гарантировать, что группа получит уведомление о завершении даже при возникновении ошибки или раннем возврате.
  • Храните результаты в массиве, используя индекс из enumerated(), чтобы сохранить порядок изображений соответствующим URL.
  • Метод group.notify(queue: .main) устанавливает обработчик, который будет вызван на главной очереди после завершения всех задач — это удобно для обновления UI.

Где применяется

Такой подход полезен в сценариях, где нужно загрузить несколько ресурсов перед отображением экрана (например, галерея изображений, аватары участников чата, миниатюры товаров). Он также может быть расширен для ограничения количества одновременных загрузок с помощью семафоров (DispatchSemaphore).

Вывод: Используйте DispatchGroup, когда вам нужно синхронизировать несколько независимых асинхронных операций и выполнить действие после их полного завершения, особенно в UI-контексте, где требуется обновить интерфейс после загрузки всех данных.

  • Аватар

    iOS Guru

    Roman Isakov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    3

  • Сложность:

    4

Навыки

  • JavaScript

    JavaScript

  • Swift

    Swift

Ключевые слова

#DispatchGroup

#async

#URLSession

#iOS

#concurrency

Подпишись на iOS Developer в телеграм

  • Аватар

    iOS Guru

    Roman Isakov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.