Ответ
Основное правило: 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.