Вопрос проверяет умение работать с параллельными задачами и корректно собирать результаты без потери порядка.
При параллельном выполнении задачи завершаются в произвольном порядке. Чтобы сохранить порядок, нужно явно его зафиксировать: использовать индекс, ассоциировать результат с ключом или заранее подготовить контейнер. В GCD это делается через массив с индексами и синхронизацию. В Swift Concurrency порядок сохраняется через async let или ручную сортировку результатов. Без дополнительной логики порядок не гарантируется.
Параллелизм почти всегда ломает естественный порядок выполнения, поэтому его нужно восстанавливать вручную.
Асинхронные задачи:
стартуют почти одновременно
выполняются с разной скоростью
зависят от сети, IO, планировщика потоков
Поэтому первая запущенная задача не обязана завершиться первой.
Самый надежный и наглядный способ.
Заранее создается массив нужного размера
Каждая задача знает свой индекс
Результат записывается строго по этому индексу
Запись синхронизируется
Пример идеи (упрощенно):
var results = Array<Data?>(repeating: nil, count: urls.count)
let queue = DispatchQueue(label: "results.queue")
for (index, url) in urls.enumerated() {
load(url) { data in
queue.async {
results[index] = data
}
}
}
После завершения всех задач массив уже упорядочен.
DispatchGroup + индексDispatchGroup отвечает за “когда все завершилось”, а индекс — за порядок.
group.enter() перед стартом
group.leave() в completion
порядок контролируется структурой хранения
Это самый частый паттерн в коде на GCD.
async let)Если количество задач фиксированное:
async let first = fetchA()
async let second = fetchB()
let results = await [first, second]
Здесь порядок определяется местом в массиве, а не временем выполнения.
TaskGroup с индексамиЕсли задач много и они динамические:
каждая задача возвращает (index, value)
результаты собираются в массив
в конце массив упорядочен по индексам
добавление результатов через append
отсутствие синхронизации при записи
ожидание, что порядок “сам сохранится”
Параллельное выполнение почти всегда разрушает порядок. Если порядок важен, его нужно сохранять явно: через индексы, ключи или структуру результата. Хорошая новость в том, что это решаемо стандартными паттернами — главное не полагаться на случайность.