Ответ
В iOS многопоточность обеспечивается системами Grand Central Dispatch (GCD), OperationQueue и, начиная с Swift 5.5, нативными async/await и Actors.
1. Grand Central Dispatch (GCD):
Фреймворк низкого уровня для управления очередями задач (очередями отправки — DispatchQueue).
- Типы очередей:
DispatchQueue.main— последовательная (serial) очередь для обновления UI.- Глобальные concurrent очереди с приоритетами QoS (
.userInteractive,.userInitiated,.utility,.background). - Собственные serial или concurrent очереди.
// Выполнение тяжелой задачи в фоне и возврат на main queue DispatchQueue.global(qos: .userInitiated).async { let processedData = self.processImage(data) DispatchQueue.main.async { self.imageView.image = processedData } }
- Синхронизация:
DispatchGroupдля ожидания завершения группы задач, барьеры (barrier) для безопасной записи в concurrent очереди, семафоры (DispatchSemaphore).
2. OperationQueue:
Абстракция更高 уровня над GCD, построенная на классах Operation. Позволяет:
- Создавать зависимые операции.
- Устанавливать приоритеты (
queuePriority). - Отменять операции (
operation.cancel()). - Ограничивать количество параллельных операций (
maxConcurrentOperationCount).
3. Swift Concurrency (async/await): Современный, безопасный и читаемый подход.
func fetchData() async throws -> Data {
let (data, _) = try await URLSession.shared.data(from: url)
return data
}
// Вызов в Task
Task {
do {
let data = try await fetchData()
await MainActor.run { self.data = data } // Безопасное обновление UI
} catch {
// Обработка ошибки
}
}
- Actors: Решают проблему гонки данных (data race) путем изоляции состояния. Доступ к свойствам actor происходит последовательно.
Best Practice: Всегда обновляйте UI только на главном потоке. Для CPU-интенсивных задач используйте фоновые очереди с подходящим QoS. Избегайте блокировок (deadlock), особенно на DispatchQueue.main. Для новых проектов предпочтительнее использовать Swift Concurrency.