Article

StateObject vs ObservedObject

Bitesize

The difference between @StateObject and @ObservedObject is ownership.

@StateObject private var model = ProfileViewModel()

Use @StateObject when the view creates the object and should keep it alive.

Use @ObservedObject when something else owns the object and the view is just watching it.

More detail

A comparison card showing StateObject ownership versus ObservedObject observation

This matters because SwiftUI can recreate views frequently. If a view creates an observable object with @ObservedObject, you can accidentally recreate the object too often.

@StateObject protects the lifecycle across view updates. @ObservedObject does not.

That makes the rule fairly simple:

  • creator and owner: @StateObject
  • external owner: @ObservedObject

That sounds small, but it affects very visible behavior. Using the wrong wrapper can lead to duplicated network work, state resetting unexpectedly, or view models being recreated every time the view hierarchy changes.

In other words, the property wrapper is about more than observation mechanics. It is a statement about lifecycle ownership inside a view system that can regenerate itself often.

Once you see that, the distinction becomes much easier to remember because it stops feeling arbitrary.

Deep dive

This distinction is really about source of truth. If the view owns the model’s lifetime, it should declare that explicitly. If ownership lives above the view, the view should not pretend otherwise.

Many SwiftUI bugs around duplicated requests, reset state, or inconsistent behavior come back to this exact mistake. The property wrapper is not only about observation; it also communicates lifecycle intent.

Once you think in terms of ownership rather than syntax, the right choice becomes much more obvious.

There is also a compositional benefit. Child views that receive an already-owned observable object via @ObservedObject stay lighter because they do not try to manage lifecycle decisions that belong elsewhere. That keeps responsibilities cleaner.

By contrast, @StateObject is strongest when a view is truly the root owner of that piece of observable state. In that role, it gives the model stability across re-renders without pushing the responsibility higher than necessary.

This connects back to a broader SwiftUI theme: identity matters. Views are cheap and transient, but some state should survive those transients. @StateObject exists to preserve that stability where appropriate.

When developers choose incorrectly, the resulting bugs often feel mysterious because the UI code still looks reasonable at a glance. But underneath, ownership is misaligned. That is why this distinction keeps surfacing in real projects.

If you evaluate the wrapper through the lens of ownership, lifetime, and identity, the decision becomes more architectural and much less memorization-based.

Finished the deep dive?

You made it to the end.

Mark this article as read once you have worked through the full piece. It is a small way to keep track of what you have genuinely finished.

More in this area

Keep the thread going.

Jump sideways into the related ideas that sit closest to this piece and keep the same mental context alive.

  1. 01 State management Explore topic