View обновляется с фоновой очереди и падает время от времени — почему и как ловить это в CI?
Этот загрузчик изображений иногда падает в проде, но редко под отладчиком. Найдите причину, исправьте код и скажите, как CI автоматически поймает такой класс багов.
Ограничения:
- Изображение всё равно должно декодироваться вне главного потока.
- На главном потоке место только обновлению UI.
URLSession.shared.dataTask(with: url) { data, _, _ in
let image = UIImage(data: data!)
self.imageView.image = image // выполняется на фоновой очереди
}.resume()
Найдите и исправьте ошибку.
UIKit не потокобезопасен — его view рассчитаны на главный поток. Обращение к imageView вне главного портит состояние, поэтому падает лишь иногда. Исправление — переход на DispatchQueue.main.async. В CI Main Thread Checker валит прогон.
- ✗Считают UIKit потокобезопасным и что любая очередь может трогать view
- ✗Винят force-unwrap вместо доступа к UI вне главного потока
- ✗Берут
main.syncтам, где правильный переход —main.async
- →Почему доступ к UIKit вне главного падает лишь иногда, а не всегда?
- →Что именно инструментирует Main Thread Checker, чтобы это обнаружить?
Замыкание dataTask выполняется на фоновой очереди URLSession, а imageView.image = … трогает UIKit вне главного потока — отсюда редкие крэши.
URLSession.shared.dataTask(with: url) { data, _, _ in
guard let data, let image = UIImage(data: data) else { return }
DispatchQueue.main.async { // возврат на главный поток
self.imageView.image = image
}
}.resume()
Декодирование UIImage(data:) остаётся на фоне; на главный поток уходит только присваивание. В CI включите Main Thread Checker (по умолчанию в Xcode) — он инструментирует вызовы UIKit и валит прогон при доступе вне главного потока.