Ответ
Методы жизненного цикла UIViewController (такие как viewDidLoad, viewWillAppear) и все операции с UI вызываются в главном потоке.
Правило: UIKit управляет контроллерами и их представлениями в главном потоке. Однако долгие задачи (сетевые запросы, работа с БД, обработка изображений) должны выполняться в фоновых потоках, чтобы не блокировать интерфейс.
Типичный паттерн разделения работы:
override func viewDidLoad() {
super.viewDidLoad() // Выполняется в главном потоке
// Запускаем фоновую задачу
DispatchQueue.global(qos: .utility).async { [weak self] in
guard let self = self else { return }
// 1. Работа в фоне (НЕ UI)
let processedData = self.loadAndProcessData()
// 2. Возврат в главный поток для обновления
DispatchQueue.main.async {
self.updateUI(with: processedData) // UI-обновление
}
}
}
Последствия нарушения:
- Зависание UI: Главный поток блокируется, интерфейс не реагирует.
- Креши: Непотокобезопасный доступ к UIKit вызывает исключения.
- Непредсказуемое поведение: Элементы интерфейса могут отображаться некорректно или с задержкой.