Когда можно обновлять UI не в главном потоке в iOS?

«Когда можно обновлять UI не в главном потоке в iOS?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основное правило: UI-компоненты UIKit/AppKit можно обновлять только в главном потоке, так как они не потокобезопасны.

Исключение: Метод drawHierarchy(in:afterScreenUpdates:) можно вызывать в фоновом потоке для рендеринга в изображение, например при создании скриншотов.

Пример легального использования в фоновом потоке:

DispatchQueue.global(qos: .background).async {
    let renderer = UIGraphicsImageRenderer(size: view.bounds.size)
    let screenshot = renderer.image { context in
        // Это безопасно в фоновом потоке
        view.drawHierarchy(in: view.bounds, afterScreenUpdates: false)
    }

    // Далее работаем с изображением (сохранение, обработка)
    UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
}

Стандартный подход для UI-обновлений:

// Всегда используйте DispatchQueue.main для UI изменений
DispatchQueue.main.async {
    self.label.text = "Новый текст"
    self.button.isEnabled = false
    self.view.backgroundColor = .systemBlue
}

Важно: SwiftUI требует обновления состояния также в главном потоке через @MainActor или DispatchQueue.main.