SwiftUI StateObject and ObservedObject

Hasancan Akgündüz
2 min readDec 19, 2021

In SwiftUI, if you want to observe changes in a reference type property, you can use @StateObject and @ObservedObject property wrappers. There is one important difference between these and I will mention at the end. Let’s start with @StateObject:

The code above tries to change the color of the text when the button is tapped. However, it does not change because the viewModel is not observed. Here’s how we make it observed:

See that the ViewModel conforms to ObservableObject protocol and the isRed property has @Published property wrapper. Also, we wrap the viewModel property with @StateObject wrapper. The result:

StateObject vs ObservedObject

They both work for the same purpose and with same mechanism. The difference is, StateObject instance is stored and it does not change when all the view is recreated which is so common in SwiftUI. ObservedObject instance might be replaced with a fresh default instance when the view is recreated. Let’s see it in action. First, a bad example for ObservedObject:

See that our viewModel has now @ObservedObject property wrapper. ContentViewWrapper wraps our ContentView. When user taps on button in ContentViewWrapper all view is redrawn so ContentView is recreated and viewModel is recreated as well since it has @ObservedObject property wrapper. This causes a problem in this example. If the user taps on button inside ContentView to make the text green and then if the button inside ContentViewWrapped is tapped, the text returns back to red because the viewModel is recreated:

If you change the @ObservedObject wrapper with @StateObject, we will see that button color is preserved because the viewModel is not recreated. So we generally use StateObject if the instance is created inside the view and we use ObservedObject if the instance is created outside and injected into it.

We can think of ObservedObject as we want to observe an object in a particular SwiftUI view which does not have the ownership of this object. However, we use StateObject if our particular SwiftUI view has the ownership of the object. Now a good example for ObservedObject:

Now, our viewModel has ObservedObject property wrapper and the object is injected by ContentViewWrapper. See that contentViewModel is a StateObject so it does not change when ContentViewWrapper is redrawn when user taps on the button inside ContentViewWrapper.

--

--