@ObservedObject: What It Is, How It Works, and Examples

Author: IT Sectr Published: 2026-06-19 Reading time: 7 min

@ObservedObject is a Property Wrapper in SwiftUI for observing an ObservableObject instance passed from outside. Unlike @StateObject, @ObservedObject does not create an object — it subscribes to changes of an existing one. According to Apple Developer Documentation (2025), @ObservedObject is used in child views that need to track data belonging to the parent. @ObservedObject provides a reactive connection without managing the object's lifecycle.

Key Takeaways

  • @ObservedObject — Property Wrapper for observing ObservableObject without ownership
  • No creation — the object is passed from the parent view or environment
  • @Published — properties inside ObservableObject whose changes SwiftUI tracks
  • Re-render — when a @Published property changes, SwiftUI updates all subscribed views
  • Not to be confused with @StateObject — @ObservedObject does not guarantee a single instance

What Is @ObservedObject in SwiftUI?

@ObservedObject is a Property Wrapper that subscribes a view to changes of an ObservableObject. ObservableObject is a protocol from the Combine framework that requires implementing an objectWillChange publisher. When any property marked with @Published changes inside the ObservedObject, the publisher sends a signal, and SwiftUI re-renders all views subscribed through @ObservedObject.

The main characteristic of @ObservedObject is lack of ownership. The view is not responsible for creating or destroying the object. The object is created in the parent view (via @StateObject) or injected through @EnvironmentObject. The child view only observes changes and receives updates. If the object is replaced in the parent, @ObservedObject switches to the new instance.

@ObservedObject is suitable for data sharing scenarios: user model, common settings, server connection state. When multiple views at different hierarchy levels need to display the same data, @ObservedObject in each view creates independent but consistent subscriptions to a single source.

@ObservedObject vs @StateObject: Key Differences

The difference between @ObservedObject and @StateObject is one of the most common interview questions about SwiftUI. The main rule: @StateObject creates and owns the object, @ObservedObject observes an existing one. Violating this rule leads to unexpected data loss or double initialization.

Characteristic@StateObject@ObservedObject
Object creationYes, on view initializationNo, receives a ready one
OwnershipCurrent viewParent component
Single instanceYes, for the entire lifecycleNo, can be replaced
Recreation on renderNo, persistsDepends on the parent
Where to useRoot view ownerChild views

@StateObject guarantees the object is created once and survives repeated initializations of the view structure. @ObservedObject receives the object from outside and is recreated with each parent structure initialization. If the parent uses @StateObject for the object, child views can safely use @ObservedObject — the object will be unique across the entire hierarchy.

How @ObservedObject Tracks Changes

The tracking mechanism of @ObservedObject is based on Combine and the ObservableObject protocol. During initialization, SwiftUI calls the objectWillChange publisher — the object must emit a signal before changing a @Published property. Combine passes the signal into the SwiftUI dependency graph, which marks all dependent views as needing an update. This happens synchronously before the value changes.

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")
        }
    }
}

In the listing WeatherService is an ObservableObject with two @Published properties. WeatherView declares @ObservedObject var weather: WeatherService, receiving the instance from the parent. When temperature changes, objectWillChange fires before setting the new value, SwiftUI re-renders WeatherView, and the actual temperature is displayed. The subscription is automatically managed by SwiftUI — the developer does not need to call sink or dispose.

@ObservedObject Usage Patterns

The first pattern is passing a model through the initializer. The parent creates an ObservableObject via @StateObject and passes it to child views as @ObservedObject. This is a standard hierarchical data transfer where the root view manages the model's lifecycle and all nested components subscribe to changes.

The second pattern is EnvironmentObject, a global version of @ObservedObject via SwiftUI Environment. The object is injected at the scene or root view level and is automatically available to all child components without explicit passing through initializers. Inside the child view, @EnvironmentObject works similarly to @ObservedObject but receives the object from the environment.

The third pattern is composition of multiple ObservableObjects. In complex applications, a view can observe several objects: @ObservedObject var user: UserService, @ObservedObject var network: NetworkMonitor. This separates responsibilities between services and maintains the testability of each component.

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

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

DashboardView observes UserViewModel and NetworkMonitor. Each object handles its own data domain and independently notifies the view of changes. If the network disconnects, NetworkMonitor changes isConnected, and SwiftUI re-renders DashboardView, updating the indicator color. Composition of ObservableObject is the preferred way to organize data in SwiftUI applications.

@Published: The Link Between ObservableObject and SwiftUI

@Published is a Property Wrapper from Combine that automatically adds a publisher to a property inside ObservableObject. When a @Published property changes, Combine generates an event through the objectWillChange publisher. SwiftUI subscribes to this publisher when using @ObservedObject or @StateObject and re-renders the view on each new value.

@Published supports all types, including optionals, collections, and custom structures. However, for collections (arrays, dictionaries) SwiftUI only tracks reference replacement, not content mutation. To detect element addition or removal, you need to reassign the entire collection or use ObservableObject with manual objectWillChange.send().

An important detail: @Published must only be used inside a class implementing ObservableObject. Using @Published outside ObservableObject will cause a compilation error. Also, @Published cannot be applied to lazy initialization properties (lazy var) or computed properties.

Common Mistakes with @ObservedObject

The most critical mistake is using @ObservedObject to create an object. If you write @ObservedObject var model = UserViewModel() in the parent view, each render will create a new UserViewModel instance. Data will be lost, and @Published subscriptions will be recreated. Always use @StateObject for creation and @ObservedObject only for receiving a ready object.

The second mistake is modifying @Published properties off the main thread. ObservableObject uses Combine, which requires sending changes on the main thread (main actor). If you change @Published in a background queue, SwiftUI may re-render the view at an inappropriate moment, causing race conditions. Use DispatchQueue.main.async or @MainActor for updates.

The third problem is cyclic updates. If a @Published change triggers side effects that again change @Published, an infinite re-render loop occurs. The solution: use guard flags (isUpdating) or separate logic across different ObservableObjects with clear responsibility boundaries.

Frequently Asked Questions

Can @ObservedObject be optional?

Yes, SwiftUI supports @ObservedObject var model: UserViewModel?. However, the view will not subscribe to changes while the object is nil. When a value is assigned, the subscription activates automatically.

How is @ObservedObject different from @EnvironmentObject?

@ObservedObject receives the object through the initializer, @EnvironmentObject through SwiftUI Environment. @EnvironmentObject does not require explicit passing through constructors, but the object must be injected at the top level of the hierarchy.

How to manually notify SwiftUI about an ObservableObject change?

Call objectWillChange.send() before changing the property. This is useful when @Published is not suitable (for example, for computed properties or collection operations where you need to report the change before mutation).

Why does @ObservedObject not re-render the view when changing inside an array?

@ObservedObject and @Published track reference replacement, not collection content mutation. To trigger a re-render, you need to reassign the array: items.append(newItem) → items = items or use objectWillChange.send() before mutation.

Can @ObservedObject be used in a struct that does not implement View?

No, @ObservedObject is a SwiftUI Property Wrapper available only inside types that implement the View protocol. For regular structs, use Combine directly with ObservableObjectPublisher.

Summary

  • @ObservedObject — Property Wrapper for observing ObservableObject without ownership
  • @StateObject — creates the object, @ObservedObject — observes an existing one
  • @Published — automatic publisher for ObservableObject properties
  • Subscription — SwiftUI automatically manages the Combine subscription when using @ObservedObject
  • Composition — a view can observe multiple ObservableObjects simultaneously
  • Main actor — @Published properties should only be changed on the main thread
  • EnvironmentObject — an alternative to @ObservedObject for implicit passing through the environment

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also