Когда следует использовать @ObservedObject в SwiftUI?

Ответ

Используйте @ObservedObject для внешних объектов данных, которые:

  1. Реализуют протокол ObservableObject.
  2. Управляются извне текущей View (их жизненным циклом владеет родительская View или другой объект).
  3. Передаются в View через параметр инициализатора.

Типичный сценарий использования:

// 1. Модель данных (внешняя по отношению к View)
class AppSettings: ObservableObject {
    @Published var username = "User"
    @Published var isDarkMode = false
}

// 2. Родительская View создает и владеет объектом
struct ParentView: View {
    @StateObject var settings = AppSettings() // Владение здесь

    var body: some View {
        ChildView(settings: settings) // Передача во вложенную View
    }
}

// 3. Дочерняя View использует @ObservedObject для подписки
struct ChildView: View {
    @ObservedObject var settings: AppSettings // Подписка, без владения

    var body: some View {
        Toggle("Dark Mode", isOn: $settings.isDarkMode)
    }
}
Ключевые отличия от @StateObject: @StateObject @ObservedObject
Создает и владеет экземпляром ObservableObject. Только подписывается на существующий экземпляр.
Жизненный цикл привязан к View, которая его объявила. Жизненный цикл зависит от внешнего владельца.
Используется, когда View источник данных. Используется, когда View потребитель данных.

Правило: Если вы создаете объект внутри View, используйте @StateObject. Если получаете его извне (через параметр), используйте @ObservedObject.

Ответ 18+ 🔞

А, слушай, смотри, тут про эту вашу SwiftUI магию. Есть у них такая штука — @ObservedObject. Ну, это как бы для чужих, пришлых данных, понимаешь?

Вот представь: есть какой-то объект, который пиздец как умный — он подписан на протокол ObservableObject. Но он не твой, блядь! Он как бы пришёл извне, им кто-то другой рулит. Твоя вьюха — она просто смотрит на него, как зритель в театре, и говорит: «О, ёпта, что-то поменялось, надо перерисоваться!»

Когда это нужно, бля?

  1. Когда объект этот — ObservableObject. Ну, логично же.
  2. Когда им управляют снаружи. Не ты его родил, не ты его и похоронишь. Его жизненный цикл — забота родительской вьюхи или ещё какого-то менеджера.
  3. Когда его тебе засунули в параметры при создании. Просто передали, типа «держи, работай».

Типичная история, как в сериале:

// 1. Модель данных (она где-то там, наверху, во дворце)
class AppSettings: ObservableObject {
    @Published var username = "User"
    @Published var isDarkMode = false
}

// 2. Родительская View — она тут главная, она всё создаёт
struct ParentView: View {
    @StateObject var settings = AppSettings() // Вот, родила! Владеет, блядь!

    var body: some View {
        ChildView(settings: settings) // И суёт этот объект ребёнку
    }
}

// 3. Дочерняя View — она просто потребитель, хитрая жопа
struct ChildView: View {
    @ObservedObject var settings: AppSettings // Приняла! Подписалась! Владеть не будет!

    var body: some View {
        Toggle("Тёмная тема", isOn: $settings.isDarkMode) // И использует
    }
}

А в чём разница с @StateObject, спросишь ты? А я тебе на пальцах, блядь:

@StateObject @ObservedObject
Создаёт и владеет объектом. Как мать. Только подписывается на уже готовый объект. Как сосед-подслушиватель.
Жизнь объекта привязана к вьюхе, которая его объявила. Умрёт вьюха — умрёт и объект. Жизнь объекта зависит от того, кто его на самом деле создал. Может жить дольше этой вьюхи.
Используется, когда вьюха — источник данных, босс. Используется, когда вьюха — потребитель данных, просто работяга.

И главное правило, чтобы не облажаться: Если ты внутри вьюхи создаёшь объект (= MyObject()) — ты его отец, используй @StateObject. Если тебе объект принесли и дали в руки (через параметр) — ты просто гость, используй @ObservedObject. Всё, вопрос закрыт, иди работай.