Что произойдет при обновлении UI из background потока?

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

Ответ

Это приведет к неопределенному поведению и крашам. UIKit не поддерживает конкурентный доступ из нескольких потоков. Конкретные последствия:

  1. Немедленный краш (в Debug с включенным Main Thread Checker).
  2. Отложенные проблемы: визуальные артефакты, "замороженный" интерфейс, некорректные layout.
  3. Трудновоспроизводимые баги, зависящие от тайминга выполнения потоков.

Пример опасного кода:

DispatchQueue.global().async {
    // ❌ КРАШ или глюки:
    self.label.text = "New Text" // UI-операция в фоновом потоке
    self.view.setNeedsLayout()   // Еще одна UI-операция
}

Как правильно:

// Паттерн "работа в фоне -> обновление UI"
DispatchQueue.global(qos: .utility).async {
    let result = performExpensiveCalculation()

    DispatchQueue.main.async {
        // ✅ Безопасное обновление на главном потоке
        self.updateUI(with: result)
    }
}

Современные альтернативы:

  • Combine: receive(on: DispatchQueue.main)
  • Async/Await:
    Task {
    let data = await networkRequest() // Может работать в фоне
    await MainActor.run { // Гарантированный переход на главный поток
        self.label.text = data
    }
    }

Важно: Даже если код "иногда работает" в фоне — это серьезная ошибка, которая проявится на других устройствах или при изменении нагрузки.