В чем разница между StateObject и ObservedObject в SwiftUI
Что проверяют
Понимаете ли вы, кто владеет объектом и что происходит при перерисовке представления. Ошибка здесь даёт сбрасывающееся состояние, которое ловят долго.
Как отвечать
SwiftUI пересоздаёт структуру представления при каждом обновлении. Разница именно в этом:
@StateObjectсоздаёт объект один раз и держит его за пределами жизненного цикла структуры. Сколько бы раз представление ни пересчитывалось, объект остаётся тем же. Это владение;@ObservedObjectтолько подписывается на уже существующий объект и им не владеет. Если создать объект прямо в теле представления с этой обёрткой, при следующей перерисовке он будет создан заново, а состояние сброшено.
Правило простое: тот, кто создаёт модель, объявляет её через @StateObject, тот, кто получает её извне, через @ObservedObject.
struct JobsScreen: View {
@StateObject private var model = JobsViewModel() // владелец
var body: some View { JobsList(model: model) }
}
struct JobsList: View {
@ObservedObject var model: JobsViewModel // получает готовую
var body: some View { ... }
}Рядом стоит назвать соседей: @EnvironmentObject для модели, прокинутой вглубь дерева; @State для простых значимых значений; а в новых версиях (iOS 17 и выше) появился макрос @Observable, где вместо этих обёрток используются @State для владения и обычное свойство для передачи.
Где спотыкаются
Пишут @ObservedObject var model = ViewModel() прямо в представлении. Работает, пока родитель не перерисуется, а потом состояние необъяснимо обнуляется.
Ждут обновления интерфейса от изменения поля, не помеченного @Published.
Создают @StateObject в дочернем представлении и удивляются, что у каждого элемента списка своя копия модели.