@State vs @ObservableObject - which and when?

你说的曾经没有我的故事 提交于 2021-01-15 22:13:21

问题


I'm currently getting familiar with SwiftUI and Combine frameworks. And I'm not really getting the difference between these two approaches. When we have to keep track of some data (say, a list of tasks), we can declare a @State variable, and it's change will automatically send notification and update current view. However, it looks like it can also be done this way:

class TaskList: ObservableObject{
    //a list that's going to be modified and updated on different occasions
    @Published var list: [String]
}

class TodoListView {
    @ObservedObject var todoList = TaskList()
}

So, I missing a point - how are @State and @ObservedObject approaches different and which one is preferable under which circumstances?

Thanks!


回答1:


If you mark any variables as @State in a SwiftUI View and bind them to a property inside the body of that View, the body will be recalculated whenever the @State variable changes and hence your whole View will be redrawn. Also, @State variables should serve as the single source of truth for a View. For these reasons, @State variables should only be accessed and updated from within the body of a View and hence should be declared private.

You should use @State when you are binding some user input (such as the value of a TextField or the chosen value from a Picker). @State should be used for value types (structs and enums).

On the other hand, @ObservedObject should be used for reference types (classes), since they trigger refreshing a view whenever any @Published property of the ObservableObject changes.

You should use @ObservedObject when you have some data coming in from outside your View, such as in an MVVM architecture with SwiftUI, your ViewModel should be stored as an @ObservedObject on your View.

A common mistake with @ObservedObjects is to declare and initialise them inside the View itself. This will lead to problems, since every time the @ObservedObject emits an update (one of its @Published properties gets updated), the view will be recreated - which will also create a new @ObservedObject, since it was initialised in the View itself. To avoid this problem, whenever you use @ObservedObject, you always have to inject it into the view. The iOS 14 @StateObject solves this issue.




回答2:


The main difference is that @State is for structs, and @ObservedObject is for classes. Both @State and @ObservedObject achieve a similar thing, of updating you when something changes.

A struct changes when some property has been mutated, which means that it gets recreated, therefore the @State is updated. A class updates @ObservedObject when a property is changed - using @Published to listen for changes. When either @State or @ObservedObject is updated, the view body gets remade.

The question you are really asking here is when to use a struct vs a class if either would work in some situations.

In your case, since TaskList is only a basic data structure and doesn't require lots of properties you want to prevent from updating the view (by using/not using @Published), you should probably use a struct with @State instead.



来源:https://stackoverflow.com/questions/61361788/state-vs-observableobject-which-and-when

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!