@ObservedObject: co to je, pozorování objektů a aktualizace View

Autor: IT Sectr Publikováno: 2026-06-26 Doba čtení: 9 min

@ObservedObject je property wrapper ve SwiftUI, který umožňuje View sledovat změny v ObservableObject vytvořeném na jiném místě hierarchie. Na rozdíl od @StateObject, @ObservedObject nevytváří objekt — pouze se přihlašuje k jeho publisheru objectWillChange a překresluje View při aktualizaci @Published vlastností. To činí @ObservedObject správnou volbou pro podřízená View, která přijímají data od rodiče přes inicializátor. Podle článku Paul Hudson — Hacking with Swift (2025) je typická architektura SwiftUI aplikace postavena takto: kořenové View používá @StateObject k vytvoření view modelu a všechna podřízená View jej získávají přes @ObservedObject, což zajišťuje jediný zdroj pravdy bez duplikování dat.

Hlavní body

  • @ObservedObject — property wrapper pro pozorování ObservableObject vytvořeném v nadřazeném View.
  • Nevlastní objekt — na rozdíl od @StateObject, @ObservedObject nespravuje životní cyklus objektu.
  • Přihlášení ke změnám — při změně @Published vlastností se View automaticky překreslí.
  • Předání přes inicializátor — objekt je předán do podřízeného View přes parametr inicializátoru.
  • iOS 13+ — @ObservedObject je dostupný od první verze SwiftUI, na rozdíl od @StateObject (iOS 14+).

Co je @ObservedObject ve SwiftUI

@ObservedObject je property wrapper, který přihlašuje View ke změnám ObservableObject. Když objekt označený @ObservedObject změní některou ze svých vlastností deklarovaných s @Published, SwiftUI automaticky překreslí View. @ObservedObject nevytváří objekt — pouze vytváří spojení mezi již existující instancí ObservableObject a View, které má reagovat na jeho změny.

Klíčový rozdíl mezi @ObservedObject a @StateObject — je vlastnictví. @ObservedObject předpokládá, že objekt byl vytvořen a uložen někde výše v hierarchii View. Podřízené View získá referenci na tento objekt přes inicializátor a jednoduše jej pozoruje. Pokud je podřízené View znovu vytvořeno, obdrží stejnou referenci od rodiče — data se neztratí.

Podle Apple Developer Documentation — SwiftUI (2025) je @ObservedObject dostupný od iOS 13, což jej činí jedinou možností pro pozorování ObservableObject v projektech podporujících staré verze iOS. V iOS 14+ je preferován @StateObject pro vytváření objektů, ale @ObservedObject zůstává relevantní pro předávání existujících objektů.

Jak @ObservedObject funguje

Mechanismus @ObservedObject je založen na protokolu ObservableObject z frameworku Combine. Každá třída odpovídající ObservableObject automaticky získá publisher objectWillChange, který vysílá signál před změnou libovolné @Published vlastnosti. SwiftUI se přihlásí k tomuto publisheru přes @ObservedObject a po přijetí signálu označí View jako vyžadující překreslení.

swift
class TaskViewModel: ObservableObject {
    @Published var tasks: [Task] = []
    @Published var isLoading = false
    
    func loadTasks() async {
        isLoading = true
        // načíst data
        isLoading = false
    }
}

struct TaskListView: View {
    @ObservedObject var viewModel: TaskViewModel
    
    var body: some View {
        List(viewModel.tasks) { task in
            Text(task.title)
        }
        .task { await viewModel.loadTasks() }
    }
}

Když nadřazené View předá viewModel do TaskListView přes inicializátor, SwiftUI vytvoří spojení mezi objektem a View. Při změně pole tasks nebo příznaku isLoading SwiftUI překreslí TaskListView. Objekt přitom zůstává nezměněn — je uložen v nadřazeném View přes @StateObject.

@ObservedObject vs @StateObject: kdy co použít

Rozdíl mezi @ObservedObject a @StateObject — je rozdíl mezi pozorovatelem a vlastníkem. @StateObject vytváří objekt a spravuje jeho životní cyklus. @ObservedObject pouze pozoruje objekt, který byl vytvořen a uložen na jiném místě. Volba mezi nimi je určena odpovědností View za data.

ScénářDoporučeníDůvod
View vytváří data@StateObjectView vlastní objekt a odpovídá za jeho životní cyklus
View přijímá data@ObservedObjectView pouze pozoruje, objekt žije v rodiči
Podpora iOS 13@ObservedObject@StateObject nedostupný, použijte @ObservedObject s ruční správou
Znovupoužitelná komponenta@ObservedObjectKomponenta by neměla vytvářet data — přijímá je zvenčí

Hlavní pravidlo: pokud View vytváří objekt — @StateObject. Pokud View přijímá objekt — @ObservedObject. Porušení tohoto pravidla ve prospěch @ObservedObject pro vytváření objektu vede ke ztrátě dat při přestavbě View. Porušení ve prospěch @StateObject pro přijímání objektu vytváří duplicitní instanci, nezávislou na rodiči.

Příklady použití @ObservedObject

Typický scénář použití @ObservedObject — seznam úkolů, kde kořenové View vytváří view model a buňka seznamu jej získává přes @ObservedObject. Každá buňka může volat metody view modelu a změny se automaticky zobrazí v celém seznamu, protože všechny buňky pozorují stejný objekt.

swift
struct TaskRow: View {
    @ObservedObject var viewModel: TaskViewModel
    let task: Task
    
    var body: some View {
        HStack {
            Text(task.title)
            Spacer()
            Button("Hotovo") {
                viewModel.completeTask(task)
            }
        }
    }
}

struct TaskListContainer: View {
    @StateObject var viewModel = TaskViewModel()
    
    var body: some View {
        List(viewModel.tasks) { task in
            TaskRow(viewModel: viewModel, task: task)
        }
    }
}

V tomto příkladu TaskListContainer vytváří viewModel přes @StateObject a každá TaskRow jej získává přes @ObservedObject. Když uživatel klikne na „Done” v libovolném řádku, viewModel.completeTask změní published vlastnost a všechna View pozorující tento objekt se automaticky aktualizují.

Typické chyby s @ObservedObject

Nejčastější chyba — použití @ObservedObject k vytvoření objektu uvnitř View. Když je View přestavěno (např. při změně state), SwiftUI vytvoří novou instanci ObservableObject, což vede ke ztrátě všech nahromaděných dat. Tato chyba je obzvláště bolestivá v NavigationStack, kde uživatel může vyplnit formulář a při návratu zpět ztratit data.

Chyba: @ObservedObject místo @StateObject

swift
// ❌ Ztráta dat: @ObservedObject neuchovává objekt
struct FormView: View {
    @ObservedObject var formVM = FormViewModel()
    // Nový formVM vytvořen při každé přestavbě View!
}

// ✅ Správně: @StateObject uchovává objekt
struct FormView: View {
    @StateObject var formVM = FormViewModel()
    // Objekt vytvořen jednou za dobu životnosti View
}

Chyba: předání @StateObject tam, kde je potřeba @ObservedObject

Pokud podřízené View deklaruje stejný ObservableObject přes @StateObject, vytvoří nezávislou kopii. Změny v nadřazeném objektu nebudou viditelné v podřízeném a naopak. Vždy používejte @ObservedObject pro podřízená View, která přijímají objekt zvenčí.

Alternativy k @ObservedObject ve SwiftUI

V moderním SwiftUI existuje několik alternativ k @ObservedObject, každá se svými výhodami. Volba závisí na architektuře aplikace, verzi iOS a konkrétním scénáři použití.

  • @EnvironmentObject — umožňuje získat objekt z prostředí SwiftUI bez explicitního předávání přes inicializátor. Pohodlný pro objekty potřebné na mnoha obrazovkách, ale vyžaduje explicitní vložení přes .environmentObject().
  • @State + @Binding — pro jednoduché typy hodnot nejsou potřeba ObservableObject. Použijte @State pro ukládání a @Binding pro předávání do podřízených View.
  • @AppStorage — pro hodnoty UserDefaults, které by se měly automaticky synchronizovat s View.
  • @SceneStorage — pro ukládání dočasného stavu mezi restartováním scény (např. pozice v seznamu).

Volba mezi @ObservedObject a @EnvironmentObject — je otázka stylu a architektury. @ObservedObject explicitně ukazuje závislosti View přes inicializátor, což činí kód předvídatelnějším. @EnvironmentObject je pohodlný pro hluboké hierarchie, ale skrývá závislosti, což může ztížit ladění.

Často kladené otázky

Lze použít @ObservedObject bez @StateObject v rodiči?

Ano, pokud je objekt vytvořen a uložen mimo SwiftUI — například v AppDelegate nebo singletonu. V tomto případě se @ObservedObject jednoduše přihlásí ke změnám existujícího objektu. Pro objekty vytvořené uvnitř SwiftUI hierarchie je však vždy potřeba @StateObject někde výše.

Proč @ObservedObject někdy neaktualizuje View?

Nejpravděpodobnější příčina — vlastnost se mění ne přes @Published nebo se nemění samotný objekt, ale jeho vnitřní struktura bez volání objectWillChange. Pro kolekce použijte přiřazení nové kopie: array.append() nestačí — je třeba znovu přiřadit celé pole přes array = array + [element].

Ovlivňuje @ObservedObject výkon?

@ObservedObject sám o sobě nevytváří významnou zátěž. Problémy vznikají při častých změnách @Published vlastností — každá změna spouští překreslení všech pozorujících View. Pro optimalizaci použijte EquatableView, snižte počet published vlastností a vyhněte se zbytečným aktualizacím.

Čím se @ObservedObject liší od @Binding?

@ObservedObject pozoruje celou třídu ObservableObject a překresluje View při každé změně jejích published vlastností. @Binding vytváří obousměrné spojení s konkrétní hodnotou (String, Int, Bool) a umožňuje ji číst a zapisovat. @Binding je lehčí a nevyžaduje ObservableObject.

Lze kombinovat @ObservedObject s @Published v jedné třídě?

Ano, to je standardní vzor. @Published uvnitř ObservableObject se automaticky integruje s @ObservedObject. Každá @Published vlastnost přidá pozorovatele k publisheru objectWillChange. Při změně libovolné z nich jsou všechna View s @ObservedObject pro tento objekt překreslena.

Shrnutí

  • @ObservedObject — property wrapper pro pozorování ObservableObject vytvořeného na jiném místě hierarchie.
  • Nevlastní objekt — na rozdíl od @StateObject, @ObservedObject nespravuje životní cyklus a nevytváří objekt.
  • Přihlášení přes Combine — SwiftUI se automaticky přihlásí k publisheru objectWillChange ObservableObject.
  • iOS 13+ — @ObservedObject je dostupný od první verze SwiftUI, důležité pro projekty se starou podporou.
  • Předání přes inicializátor — objekt je explicitně předán do podřízeného View, což činí závislosti transparentními.
  • Chyba vlastnictví — použití @ObservedObject k vytvoření objektu vede ke ztrátě dat při přestavbě View.
  • Alternativy — @EnvironmentObject pro vložení přes prostředí, @State/@Binding pro typy hodnot.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také