@ObservedObject is een Property Wrapper in SwiftUI voor het observeren van een van buitenaf doorgegeven ObservableObject-instantie. In tegenstelling tot @StateObject maakt @ObservedObject geen object aan — het abonneert zich op wijzigingen van een bestaand object. Volgens Apple Developer Documentation (2025) wordt @ObservedObject gebruikt in kind-views die gegevens moeten volgen die aan de ouder toebehoren. @ObservedObject zorgt voor een reactieve verbinding zonder het levenscyclusbeheer van het object.
Belangrijkste
@ObservedObject is een Property Wrapper die een view abonneert op wijzigingen van ObservableObject. ObservableObject is een protocol uit het Combine-framework dat de implementatie van een objectWillChange-publisher vereist. Wanneer een eigenschap gemarkeerd met @Published binnen ObservableObject verandert, stuurt de publisher een signaal en hertekent SwiftUI alle views die via @ObservedObject zijn geabonneerd.
De belangrijkste eigenschap van @ObservedObject is geen eigendom. De view is niet verantwoordelijk voor het aanmaken of vernietigen van het object. Het object wordt aangemaakt in de ouder-view (via @StateObject) of geïnjecteerd via @EnvironmentObject. De kind-view observeert alleen wijzigingen en ontvangt updates. Als het object in de ouder wordt vervangen, schakelt @ObservedObject over naar de nieuwe instantie.
@ObservedObject is geschikt voor scenario's met gegevensdeling: gebruikersmodel, gedeelde instellingen, verbindingsstatus met de server. Wanneer meerdere views op verschillende niveaus van de hiërarchie dezelfde gegevens moeten weergeven, creëert @ObservedObject in elke view onafhankelijke maar gecoördineerde abonnementen op één bron.
Het verschil tussen @ObservedObject en @StateObject is een van de meest gestelde onderwerpen in SwiftUI-interviews. De basisregel: @StateObject maakt en bezit het object, @ObservedObject observeert een bestaand object. Overtreding van deze regel leidt tot onverwacht gegevensverlies of dubbele initialisatie.
| Kenmerk | @StateObject | @ObservedObject |
|---|---|---|
| Object aanmaken | Ja, bij initialisatie van de view | Nee, ontvangt kant-en-klaar |
| Eigendom | Huidige view | Oudercomponent |
| Unieke instantie | Ja, gedurende de hele levenscyclus | Nee, kan worden vervangen |
| Hercreatie bij render | Nee, blijft behouden | Afhankelijk van ouder |
| Waar gebruiken | Root view-eigenaar | Kind-views |
@StateObject garandeert dat het object één keer wordt aangemaakt en herhaalde initialisaties van de view-structuur overleeft. @ObservedObject ontvangt het object van buitenaf en wordt opnieuw aangemaakt bij elke initialisatie van de ouderstructuur. Als de ouder @StateObject gebruikt voor het object, kunnen kind-views veilig @ObservedObject toepassen — het object zal uniek zijn in de hele hiërarchie.
Het trackingmechanisme van @ObservedObject is gebaseerd op Combine en het ObservableObject-protocol. Bij initialisatie roept SwiftUI de objectWillChange-publisher aan — het object moet een signaal uitzenden voordat de @Published-eigenschap verandert. Combine geeft het signaal door aan de afhankelijkheidsgraaf van SwiftUI, die alle afhankelijke views markeert als updates vereisend. Dit gebeurt synchroon voordat de waarde verandert.
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")
}
}
}
In de listing is WeatherService een ObservableObject met twee @Published-eigenschappen. WeatherView declareert @ObservedObject var weather: WeatherService en ontvangt de instantie van de ouder. Wanneer temperature verandert, wordt objectWillChange geactiveerd voordat de nieuwe waarde wordt ingesteld, hertekent SwiftUI WeatherView en wordt de actuele temperatuur weergegeven. Het abonnement wordt automatisch beheerd door SwiftUI — de ontwikkelaar hoeft geen sink of dispose aan te roepen.
Het eerste patroon — model doorgeven via initialisator. De ouder maakt ObservableObject aan via @StateObject en geeft het door aan kind-views als @ObservedObject. Dit is een standaard hiërarchische gegevensoverdracht waarbij de root-view de levenscyclus van het model beheert en alle geneste componenten zich abonneren op wijzigingen.
Het tweede patroon — EnvironmentObject, de globale versie van @ObservedObject via SwiftUI Environment. Het object wordt geïnjecteerd op sceneniveau of root-view-niveau en is automatisch beschikbaar voor alle kind-componenten zonder expliciete overdracht via initialisatoren. Binnen de kind-view werkt @EnvironmentObject vergelijkbaar met @ObservedObject, maar haalt het object uit de omgeving.
Het derde patroon — compositie van meerdere ObservableObjecten. In complexe applicaties kan een view meerdere objecten observeren: @ObservedObject var user: UserService, @ObservedObject var network: NetworkMonitor. Dit verdeelt de verantwoordelijkheid tussen services en behoudt de testbaarheid van elke component.
struct DashboardView: View {
@ObservedObject var user: UserViewModel
@ObservedObject var network: NetworkMonitor
var body: some View {
VStack {
Text("Welkom, \\(user.name)")
HStack {
Circle()
.fill(network.isConnected ? Color.green : Color.red)
.frame(width: 10, height: 10)
}
}
}
}
DashboardView observeert UserViewModel en NetworkMonitor. Elk object is verantwoordelijk voor zijn eigen gegevensdomein en stelt de view onafhankelijk op de hoogte van wijzigingen. Als het netwerk wordt verbroken, wijzigt NetworkMonitor isConnected en hertekent SwiftUI DashboardView, waarbij de indicator van kleur verandert. Compositie van ObservableObjecten is de voorkeursmanier voor gegevensorganisatie in SwiftUI-applicaties.
@Published is een Property Wrapper uit Combine die automatisch een publisher toevoegt aan een eigenschap binnen ObservableObject. Wanneer de @Published-eigenschap verandert, genereert Combine een gebeurtenis via de objectWillChange-publisher. SwiftUI abonneert zich op deze publisher bij gebruik van @ObservedObject of @StateObject en hertekent de view bij elke nieuwe waarde.
@Published ondersteunt alle typen, inclusief optionele, collecties en aangepaste structuren. Voor collecties (arrays, woordenboeken) volgt SwiftUI echter alleen de vervanging van de referentie, niet de wijziging van de inhoud. Om toevoeging of verwijdering van een element te detecteren, moet de hele collectie opnieuw worden toegewezen of ObservableObject met handmatige objectWillChange.send() worden gebruikt.
Een belangrijk detail: @Published mag alleen binnen een klasse staan die ObservableObject implementeert. Gebruik van @Published buiten ObservableObject veroorzaakt een compilatiefout. Ook kan @Published niet worden toegepast op eigenschappen met luie initialisatie (lazy var) of berekende eigenschappen (computed property).
De meest kritieke fout — het gebruik van @ObservedObject om een object aan te maken. Als u @ObservedObject var model = UserViewModel() in de ouder-view schrijft, wordt bij elke render een nieuwe UserViewModel-instantie aangemaakt. Gegevens gaan verloren en @Published-abonnementen worden opnieuw aangemaakt. Gebruik altijd @StateObject voor het aanmaken en @ObservedObject alleen voor het ontvangen van een kant-en-klaar object.
De tweede fout — het wijzigen van @Published-eigenschappen buiten de hoofdthread. ObservableObject gebruikt Combine, dat vereist dat wijzigingen op de hoofdthread (main actor) worden verzonden. Als u @Published in een achtergrondwachtrij wijzigt, kan SwiftUI de view op een ongelegen moment hertekenen, wat race conditions veroorzaakt. Gebruik DispatchQueue.main.async of @MainActor voor updates.
Het derde probleem — cyclische updates. Als een @Published-wijziging neveneffecten heeft die opnieuw @Published wijzigen, ontstaat een oneindige hertekenlus. Oplossing: gebruik beschermingsvlaggen (isUpdating) of verdeel de logica over verschillende ObservableObjecten met duidelijke verantwoordelijkheidsgrenzen.
Veelgestelde vragen
Ja, SwiftUI ondersteunt @ObservedObject var model: UserViewModel?. De view zal echter niet zijn geabonneerd op wijzigingen zolang het object nil is. Bij toewijzing van een waarde wordt het abonnement automatisch geactiveerd.
@ObservedObject ontvangt het object via een initialisator, @EnvironmentObject via SwiftUI Environment. @EnvironmentObject vereist geen expliciete overdracht via constructors, maar het object moet op het bovenste niveau van de hiërarchie zijn geïnjecteerd.
Roep objectWillChange.send() aan vóór de wijziging van de eigenschap. Dit is handig als @Published niet geschikt is (bijvoorbeeld voor berekende eigenschappen of bewerkingen met collecties waarbij de wijziging vóór mutatie moet worden gemeld).
@ObservedObject en @Published volgen de vervanging van de referentie, niet de mutatie van de collectie-inhoud. Voor hertekenen moet de array opnieuw worden toegewezen: items.append(newItem) → items = items of objectWillChange.send() vóór mutatie worden gebruikt.
Nee, @ObservedObject is een SwiftUI Property Wrapper die alleen beschikbaar is binnen typen die het View-protocol implementeren. Gebruik voor gewone structuren Combine rechtstreeks met ObservableObjectPublisher.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook