В чем разница ререндеринга и реклэйшна в SwiftUI?
Что проверяют
Понимаете ли вы, как SwiftUI обновляет экран: что пересчитывается при изменении состояния, что сравнивается и когда view теряет своё состояние. Термины неофициальные: «реклэйшн» обычно означает либо сравнение нового дерева со старым (reconciliation, слово из React), либо пересоздание view, так что разберите оба смысла. Следом почти всегда спрашивают, почему @State внезапно сбросился.
Как отвечать
- создание структур: view в SwiftUI это лёгкие значения-описания. Их создают постоянно, это дёшево и ничего не рисует;
- пересчёт
body: когда меняется зависимость (@State,@Binding, наблюдаемая модель,Environment), SwiftUI заново вызываетbodyэтой view. Это и называют ререндерингом, хотя пиксели ещё не перерисованы; - сравнение: новый результат
bodyсопоставляется с прошлым, и в слои отображения уходят только отличия. Состояние сохраняется, потому что идентичность view не изменилась; - смена идентичности: если меняется структурная идентичность (другая ветка
if/else) или явная (.id(...),idэлемента вForEach), SwiftUI считает это новой view. Старая уничтожается вместе с@State, заново срабатываютonAppearи.task, анимация идёт как удаление и вставка.
Для диагностики назовите Self._printChanges() внутри body: он печатает, какое свойство вызвало пересчёт. Для производительности: мелкие view с узкими зависимостями и макрос @Observable (iOS 17+), который следит за чтением отдельных свойств, тогда как у ObservableObject любое изменение @Published задевает всех подписчиков. Ещё помогают .equatable() и стабильные id в списках.
Где спотыкаются
Считают, что пересчёт body означает перерисовку всего экрана. Это дешёвое вычисление, дорогим оно становится, когда в body сидит тяжёлая работа вроде форматирования дат или фильтрации массива.
Используют в ForEach индексы или \.self для неуникальных значений. Идентичность прыгает, строки пересоздаются, теряют состояние и анимируются неправильно.
Заворачивают всё в AnyView или ставят .id(UUID()), чтобы «обновить» экран. Первое прячет от SwiftUI структуру дерева, второе гарантирует пересоздание view на каждом проходе.