@ObservedObject: co to je, jak to funguje a příklady

Autor: IT Sectr Publikováno: 2026-06-19 Doba čtení: 7 min

@ObservedObject je Property Wrapper ve SwiftUI pro pozorování instance ObservableObject předané zvenčí. Na rozdíl od @StateObject, @ObservedObject objekt nevytváří — přihlašuje se ke změnám již existujícího. Podle Apple Developer Documentation (2025) se @ObservedObject používá v podřízených view, která potřebují sledovat data patřící rodiči. @ObservedObject poskytuje reaktivní spojení bez správy životního cyklu objektu.

Hlavní

  • @ObservedObject — Property Wrapper pro pozorování ObservableObject bez vlastnictví
  • Bez vytváření — objekt je předán z rodičovského view nebo prostředí
  • @Published — vlastnosti uvnitř ObservableObject, jejichž změny SwiftUI sleduje
  • Překreslení — při změně @Published vlastnosti SwiftUI aktualizuje všechna přihlášená view
  • Nezaměňovat s @StateObject — @ObservedObject nezaručuje jedinou instanci

Co je @ObservedObject ve SwiftUI?

@ObservedObject je Property Wrapper, který přihlašuje view ke změnám ObservableObject. ObservableObject je protokol z frameworku Combine, který vyžaduje implementaci publisheru objectWillChange. Když se jakákoli vlastnost označená @Published změní uvnitř ObservableObject, publisher odešle signál a SwiftUI překreslí všechna view přihlášená přes @ObservedObject.

Hlavní vlastností @ObservedObject je absence vlastnictví. View není odpovědné za vytvoření nebo zničení objektu. Objekt je vytvořen v rodičovském view (přes @StateObject) nebo vložen přes @EnvironmentObject. Podřízené view pouze pozoruje změny a přijímá aktualizace. Pokud je objekt v rodiči nahrazen, @ObservedObject přepne na novou instanci.

@ObservedObject je vhodný pro scénáře sdílení dat: model uživatele, společná nastavení, stav připojení k serveru. Když několik view na různých úrovních hierarchie musí zobrazovat stejná data, @ObservedObject v každém view vytváří nezávislá, ale koordinovaná přihlášení k jednomu zdroji.

@ObservedObject vs @StateObject: klíčové rozdíly

Rozdíl mezi @ObservedObject a @StateObject je jedním z nejčastějších témat otázek na pohovorech o SwiftUI. Základní pravidlo: @StateObject vytváří a vlastní objekt, @ObservedObject pozoruje již existující. Porušení tohoto pravidla vede k neočekávané ztrátě dat nebo dvojité inicializaci.

Charakteristika@StateObject@ObservedObject
Vytvoření objektuAno, při inicializaci viewNe, přijímá hotový
VlastnictvíAktuální viewRodičovská komponenta
Jediná instanceAno, po celý životní cyklusNe, může být nahrazena
Znovuvytvoření při renderuNe, zachovává seZávisí na rodiči
Kde použítKořenové view-vlastníkPodřízená view

@StateObject zaručuje, že objekt je vytvořen jednou a přežije opakované inicializace struktury view. @ObservedObject přijímá objekt zvenčí a je znovu vytvořen při každé inicializaci rodičovské struktury. Pokud rodič používá @StateObject pro objekt, podřízená view mohou bezpečně aplikovat @ObservedObject — objekt bude v celé hierarchii jedinečný.

Jak @ObservedObject sleduje změny

Mechanismus sledování @ObservedObject je založen na Combine a protokolu ObservableObject. Při inicializaci SwiftUI volá publisher objectWillChange — objekt musí vyslat signál před změnou @Published vlastnosti. Combine předá signál do grafu závislostí SwiftUI, který označí všechna závislá view jako vyžadující aktualizaci. To se děje synchronně před změnou hodnoty.

swift
class WeatherService: ObservableObject {
    @Published var temperature: Double = 22.0
    @Published var city: String = "Moscow"
}

struct WeatherView: View {
    @ObservedObject var weather: WeatherService

    var body: some View {
        VStack {
            Text("\\(weather.city)")
            Text("\\(weather.temperature)°C")
        }
    }
}

Ve výpisu je WeatherService ObservableObject se dvěma @Published vlastnostmi. WeatherView deklaruje @ObservedObject var weather: WeatherService, přičemž instanci získává od rodiče. Když se temperature změní, objectWillChange se aktivuje před nastavením nové hodnoty, SwiftUI překreslí WeatherView a zobrazí se aktuální teplota. Přihlášení je automaticky spravováno SwiftUI — vývojář nemusí volat sink ani dispose.

Vzory použití @ObservedObject

První vzor — předání modelu přes inicializátor. Rodič vytvoří ObservableObject přes @StateObject a předá jej podřízeným view jako @ObservedObject. Toto je standardní hierarchické předávání dat, kde kořenové view spravuje životní cyklus modelu a všechny vnořené komponenty se přihlašují ke změnám.

Druhý vzor — EnvironmentObject, globální verze @ObservedObject přes SwiftUI Environment. Objekt je vložen na úrovni scény nebo kořenového view a je automaticky dostupný všem podřízeným komponentám bez explicitního předávání přes inicializátory. Uvnitř podřízeného view funguje @EnvironmentObject podobně jako @ObservedObject, ale získává objekt z prostředí.

Třetí vzor — kompozice více ObservableObject. Ve složitých aplikacích může view pozorovat více objektů: @ObservedObject var user: UserService, @ObservedObject var network: NetworkMonitor. To rozděluje odpovědnost mezi služby a zachovává testovatelnost každé komponenty.

swift
struct DashboardView: View {
    @ObservedObject var user: UserViewModel
    @ObservedObject var network: NetworkMonitor

    var body: some View {
        VStack {
            Text("Vítejte, \\(user.name)")
            HStack {
                Circle()
                    .fill(network.isConnected ? Color.green : Color.red)
                    .frame(width: 10, height: 10)
            }
        }
    }
}

DashboardView pozoruje UserViewModel a NetworkMonitor. Každý objekt je odpovědný za svou doménu dat a nezávisle informuje view o změnách. Pokud se síť odpojí, NetworkMonitor změní isConnected a SwiftUI překreslí DashboardView a aktualizuje barvu indikátoru. Kompozice ObservableObject je preferovaný způsob organizace dat v aplikacích SwiftUI.

@Published: propojení ObservableObject a SwiftUI

@Published je Property Wrapper z Combine, který automaticky přidává vydavatele k vlastnosti uvnitř ObservableObject. Když se @Published vlastnost změní, Combine vygeneruje událost přes publisher objectWillChange. SwiftUI se k tomuto publisheru přihlásí při použití @ObservedObject nebo @StateObject a překreslí view při každé nové hodnotě.

@Published podporuje všechny typy, včetně volitelných, kolekcí a vlastních struktur. U kolekcí (pole, slovníky) však SwiftUI sleduje pouze nahrazení reference, nikoli změnu obsahu. Pro detekci přidání nebo odebrání prvku je třeba znovu přiřadit celou kolekci nebo použít ObservableObject s ručním objectWillChange.send().

Důležitý detail: @Published se musí nacházet pouze uvnitř třídy implementující ObservableObject. Použití @Published mimo ObservableObject způsobí chybu kompilace. Také @Published nelze aplikovat na vlastnosti s línou inicializací (lazy var) nebo vypočítané vlastnosti (computed property).

Typické chyby s @ObservedObject

Nejkritičtější chyba — použití @ObservedObject k vytvoření objektu. Pokud napíšete @ObservedObject var model = UserViewModel() v rodičovském view, při každém renderu bude vytvořena nová instance UserViewModel. Data budou ztracena a @Published přihlášení budou znovu vytvořena. Vždy používejte @StateObject pro vytvoření a @ObservedObject pouze pro příjem hotového objektu.

Druhá chyba — změna @Published vlastností mimo hlavní vlákno. ObservableObject používá Combine, který vyžaduje odesílání změn na hlavním vlákně (main actor). Pokud změníte @Published v běžné frontě na pozadí, SwiftUI může překreslit view v nevhodnou chvíli, což způsobí race conditions. Pro aktualizaci použijte DispatchQueue.main.async nebo @MainActor.

Třetí problém — cyklické aktualizace. Pokud změna @Published zahrnuje vedlejší účinky, které znovu změní @Published, vznikne nekonečná smyčka překreslování. Řešení: používejte ochranné příznaky (isUpdating) nebo rozdělte logiku na různé ObservableObject s jasnými hranicemi odpovědnosti.

Často kladené otázky

Může být @ObservedObject volitelný?

Ano, SwiftUI podporuje @ObservedObject var model: UserViewModel?. View se však nebude přihlašovat ke změnám, dokud je objekt nil. Při přiřazení hodnoty se přihlášení automaticky aktivuje.

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

@ObservedObject přijímá objekt přes inicializátor, @EnvironmentObject přes SwiftUI Environment. @EnvironmentObject nevyžaduje explicitní předávání přes konstruktory, ale objekt musí být vložen na horní úrovni hierarchie.

Jak ručně upozornit SwiftUI na změnu ObservableObject?

Zavolejte objectWillChange.send() před změnou vlastnosti. To je užitečné, pokud @Published není vhodný (například pro vypočítané vlastnosti nebo operace s kolekcemi, kde je třeba ohlásit změnu před mutací).

Proč @ObservedObject nepřekresluje view při změně uvnitř pole?

@ObservedObject a @Published sledují nahrazení reference, nikoli mutaci obsahu kolekce. Pro překreslení je třeba znovu přiřadit pole: items.append(newItem) → items = items nebo použít objectWillChange.send() před mutací.

Lze @ObservedObject použít ve struktuře, která neimplementuje View?

Ne, @ObservedObject je Property Wrapper SwiftUI dostupný pouze uvnitř typů implementujících protokol View. Pro běžné struktury použijte Combine přímo s ObservableObjectPublisher.

Shrnutí

  • @ObservedObject — Property Wrapper pro pozorování ObservableObject bez vlastnictví
  • @StateObject — vytváří objekt, @ObservedObject — pozoruje existující
  • @Published — automatický vydavatel pro vlastnosti ObservableObject
  • Přihlášení — SwiftUI automaticky spravuje přihlášení Combine při použití @ObservedObject
  • Kompozice — view může pozorovat více ObservableObject současně
  • Main actor — @Published vlastnosti by měly být měněny pouze na hlavním vlákně
  • EnvironmentObject — alternativa k @ObservedObject pro implicitní předávání přes prostředí

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é