Ответ
Да, можно, но с осторожностью. @StateObject предназначен для хранения и управления жизненным циклом объекта, соответствующего протоколу ObservableObject, внутри конкретного View. Отказаться от него можно в следующих сценариях:
1. Когда объект передаётся извне (родительского View)
Используйте @ObservedObject. SwiftUI не будет управлять его жизненным циклом.
struct ChildView: View {
@ObservedObject var viewModel: SharedViewModel // Передан из родителя
var body: some View { ... }
}
2. Когда объект является общим для всей иерархии
Используйте @EnvironmentObject. Объект вставляется в окружение родительским View.
struct ContentView: View {
@EnvironmentObject var appCoordinator: AppCoordinator
var body: some View { ... }
}
3. Когда данные простые и локальные
Для простых значений используйте @State.
@State private var isEnabled: Bool = false
Критически важное правило:
Не используйте @ObservedObject для инициализации объекта внутри View.
// НЕПРАВИЛЬНО! Объект будет пересоздан при каждой перерисовке View.
@ObservedObject var viewModel = MyViewModel()
// ПРАВИЛЬНО! SwiftUI сохранит объект при перерисовках.
@StateObject var viewModel = MyViewModel()
Итог: Используйте @StateObject для объектов, источником которых является само View. Для объектов, передаваемых сверху или общих, используйте @ObservedObject или @EnvironmentObject.
Ответ 18+ 🔞
А, слушай, смотри, тут про эту вашу SwiftUI-шную магию. Ну, @StateObject, блядь. Штука, конечно, мощная, но не везде её тыкать надо, как гвоздь в стену, когда молоток в жопе.
Вот представь: этот @StateObject — он как твой личный, ёпта, телохранитель. Он рождается, живёт и помирает вместе с конкретным View. За ним присматривает сам SwiftUI, чтобы при каждой перерисовке твоего интерфейса он не перерождался заново, как феникс из пепла, а спокойно себе существовал. Это его дом, его крепость.
Но иногда, блядь, этот телохранитель не нужен. Иногда к тебе в гости заходит соседский ViewModel, и ты просто даёшь ему посидеть на диване. Вот для этого есть другие инструменты.
1. Когда объект пришёл со стороны (как тёща в гости)
Тут @StateObject — это перебор, ядрёна вошь. Используй @ObservedObject. Ты просто смотришь на него, наблюдаешь, но не отвечаешь за его рождение и смерть. Это забота того, кто его тебе передал.
struct ДочернийВид: View {
@ObservedObject var вьюМодель: ОбщаяВьюМодель // Пришла от родителя, как незваный гость
var body: some View { ... }
}
2. Когда объект — как воздух в комнате, он везде
Ну, типа глобальный менеджер, координатор приложения. Тащить его через все View — это пиздец какой геморрой. Для этого есть @EnvironmentObject. Кинул его в окружение у самого корня — и все дети могут до него дотянуться, как до вазочки с печеньем.
struct ГлавныйВид: View {
@EnvironmentObject var координатор: КоординаторПриложения // Достал из воздуха
var body: some View { ... }
}
3. Когда всё просто, как три копейки
Зачем, блядь, заводить целый ObservableObject для какой-нибудь флаговой переменной isButtonTapped? Это же, прости господи, из пушки по воробьям. Бери @State и не морочь голову.
@State private var кнопкаНажата: Bool = false // Всё, вопрос закрыт.
А теперь, внимание, ебать мои старые костыли, ГЛАВНОЕ ПРАВИЛО:
Никогда, слышишь, НИКОГДА не инициализируй @ObservedObject прямо внутри View.
Смотри, что получается:
// ЭТО ПИЗДЕЦ, НЕ ДЕЛАЙ ТАК!
// При каждой перерисовке View будет создаваться НОВЫЙ объект. Старый — на свалку истории.
@ObservedObject var viewModel = MyViewModel()
// А ВОТ ЭТО — ПРАВИЛЬНО, ДА!
// SwiftUI скажет: "О, так это твой личный телохранитель? Ну ок, я его берегу."
@StateObject var viewModel = MyViewModel()
Видишь разницу? В первом случае ты каждый раз нового телохранителя нанимаешь, а старого в окно выкидываешь. Дороговато выйдет, да и логика твоя накроется медным тазом.
Короче, вывод, блядь:
@StateObject — это для твоих личных, доморощенных объектов, которые живут и умирают с этим View.
Если объект пришёл извне (@ObservedObject) или он общий для всех (@EnvironmentObject) — используй другие инструменты. А для мелочи — хватит и @State.
Вот и вся философия, в рот меня чих-пых. Не усложняй, где не надо.