@StateObject vs. @ObservedObject: The differences explained – onlinecode

@StateObject vs. @ObservedObject: The differences explained – onlinecode

In this post we will give you information about @StateObject vs. @ObservedObject: The differences explained – onlinecode. Hear we will give you detail about @StateObject vs. @ObservedObject: The differences explained – onlinecodeAnd how to use it also give you demo for it if it is necessary.

The @StateObject and @ObservedObject property wrappers tell a SwiftUI view to update in response to changes from an observed object. Both wrappers look similar but have an essential distinction to be aware of when building apps in SwiftUI.

At first, you might wonder why you wouldn’t just always use @ObservedObject. I thought the same for a while since both looked so similar to me. However, I only started to realize how badly I needed @StateObject in some cases once I knew about its purpose in SwiftUI.

Architecting SwiftUI apps with MVC and MVVMAlthough you can create an app simply by throwing some code together, without best practices and a robust architecture, you’ll soon end up with unmanageable spaghetti code. Learn how to create solid and maintainable apps with fewer bugs using this free guide.

What is an @ObservedObject?

Before diving into the differences between @StateObject and @ObservedObject, it’s good to understand what an @ObservedObject is. Both property wrappers require your object to conform to the ObservableObject protocol. This protocol stands for an object with a publisher that emits before the object has changed and allows you to tell SwiftUI to trigger a view redraw.

Types conforming to the ObservableObject can be combined with the @ObservedObject property wrapper to connect the SwiftUI view and make it redraw after a detected change inside the observed object.

A classic example would be a counter view:

final class CounterViewModel: ObservableObject {
    @Published var count = 0

    func incrementCounter() {
        count += 1
    }
}

struct CounterView: View {
    @ObservedObject var viewModel = CounterViewModel()

    var body: some View {
        VStack {
            Text("Count is: (viewModel.count)")
            Button("Increment Counter") {
                viewModel.incrementCounter()
            }
        }
    }
}

We can define our view model as @ObservedObject since the CounterViewModel conforms to the ObservableObject protocol. The count property inside the view model increments once the button fires, and the @Published property makes sure all observers receive a changed signal.

To better understand how a change delegates through observers, we could modify the above code to no longer use the @Published property wrapper. Instead, we’ll make use of the observable object publisher and send a change signal manually:

final class CounterViewModel: ObservableObject {
    private(set) var count = 0

    func incrementCounter() {
        count += 1
        objectWillChange.send()
    }
}

You’ll see the view still updates once the increment method executes. In most cases, we don’t need to call into the objectWillChange.send() method manually. However, it might be a better solution if you’re updating multiple published properties at once to mark those properties as regular arguments and use the manual signal instead.

The above examples demonstrate how a SwiftUI view redraws based on detected changes inside the observed object. Let’s dive into the @StateObject property wrapper to see how it differs.

What is a @StateObject?

The @StateObject property wrapper works similarly to the @ObservedObject. We could change our previous code example to use the @StateObject property wrapper instead, and nothing seems to be changed:

struct CounterView: View {
    /// Using @StateObject instead of @ObservedObject
    @StateObject var viewModel = CounterViewModel()

    var body: some View {
        VStack {
            Text("Count is: (viewModel.count)")
            Button("Increment Counter") {
                viewModel.incrementCounter()
            }
        }
    }
}

The fact that nothing changes is precisely why I often decided to use @ObservedObject. However, there’s a significant difference in making it clear when to use @StateObject instead of @ObservedObject.

Observed objects marked with the @StateObject property wrapper don’t get destroyed and re-instantiated at times their containing view struct redraws. Understanding this difference is essential in cases another view contains your view.

To demonstrate how this works, we can wrap our earlier used counter view inside another view:

struct RandomNumberView: View {
    @State var randomNumber = 0

    var body: some View {
        VStack {
            Text("Random number is: (randomNumber)")
            Button("Randomize number") {
                randomNumber = (0..<1000).randomElement()!
            }
        }.padding(.bottom)
        
        CounterView()
    }
}

The random number view allows you to generate a random number by pressing the randomize button. The randomNumber property marked by the @State property wrapper will redraw the view causing our CounterView to be regenerated.

You’ll see the counter resetting if we use @ObservedObject inside our CounterView once a new random number generates:

The fix is as simple as changing the CounterView view model property to be a @StateObject instead of an @ObservedObject. As described above, the state object makes sure the view model retains between view redraws and ensures our counter values remain the same.

So, when should I use a @StateObject?

Right, we now know how both work, but it might be good to understand better when to use the @StateObject over the @ObservedObject property wrapper.

It’s unsafe to create an @ObservedObject inside a view since SwiftUI might create or recreate a view at any time. Unless you inject the @ObservedObject as a dependency, you want to use the @StateObject wrapper to ensure consistent results after a view redraw.

Should I use @StateObject for all views using the same instance?

Siblings observing the same @StateObject instance down the line don’t require marking the object with this property wrapper. It’s important not to do this since you’ll ask to retain and manage the object’s lifecycle in two places. As described in the previous section: if you inject the observed object, you should use @ObservedObject.

Architecting SwiftUI apps with MVC and MVVMAlthough you can create an app simply by throwing some code together, without best practices and a robust architecture, you’ll soon end up with unmanageable spaghetti code. Learn how to create solid and maintainable apps with fewer bugs using this free guide.

Conclusion

@StateObject and @ObservedObject have similar characteristics but differ in how SwiftUI manages their lifecycle. Use the state object property wrapper to ensure consistent results when the current view creates the observed object. Whenever you inject an observed object as a dependency, you can use the @ObservedObject.

If you like to improve your SwiftUI knowledge, even more, check out the SwiftUI category page. Feel free to contact me or tweet me on Twitter if you have any additional tips or feedback.

Thanks!

<!– Disable cross link to Medium



Also published on Medium.

–>

 

Hope this code and post will helped you for implement @StateObject vs. @ObservedObject: The differences explained – onlinecode. if you need any help or any feedback give it in comment section or you have good idea about this post you can give it comment section. Your comment will help us for help you more and improve us. we will give you this type of more interesting post in featured also so, For more interesting post and code Keep reading our blogs

For More Info See :: laravel And github

We're accepting well-written guest posts and this is a great opportunity to collaborate : Contact US