I created a model like this
import Foundation
class Play:ObservableObject{
@Published var name:String="Tayle"
@Published var age:Int=12
}
It will be used in two views
For example:
struct Demo: View {
//1
@State private var play:Play = Play()
//2
//@StateObject private var play:Play = Play()
var body: some View {
NavigationView{
NavigationLink(destination: PlayNameView(play: play)){
Text("go to platnbame")
}
}
}
}
struct PlayNameView:View{
@ObservedObject var play:Play
var body: some View{
HStack{
Text("Hello,(play.name)")
Button(action:{
play.name="iop"
}){
Text("change the name to:iop")
}
}
}
}
When I run the project,they have the same behavior. If @StateObject can do it,why choose @State
2
Answers
@State
is a variable that is meant to hold value types such as Bools, Integers, Strings, structs and so on. Apple simply doesn’t intend for@State
to be used on reference types such asObservableObjects
, because once again, State is meant to store value types such as Int, not instances of classes. Apple says in the documentation,In short, you could use
@State
variables to store, say, the number of times a user has clicked a button (since the app started), but not to store anotherObservableObject
. Also, if you look at this, the article shows that using an Object with State will not cause the view’s actual variable to update. This is because, again to quote the article,An
@StateObject
, on the other hand, can store things such asObservableObjects
. When the value of the Object changes, it will cause a view update, because all of it is observed bySwiftUI
. This will only happen with@Published
properties, though, and any change of those properties will, once again, cause the view to re-render. An important note, too:@StateObject
will create a new instance every time the view appears. If you need to persist the values, you would need to pass in the object from a more root view. Also, an@StateObject
can be changed from outside the view, whereas@State
variables are only intended to be private and local. For more information on why this is, refer to the AppleState
documentation: https://developer.apple.com/documentation/swiftui/stateResources:
For Objects use the
@StateObject
property wrapper. For String, Int, etc use@State
property wrapper.@State
: We use this property wrapper when we observe a property that is exists inside our ContentView.@StateObject
: We use this property wrapper when we are observing properties that exists outside of our ContentView like in our Object, we can observe that property changes by firstly conforming that class toObservableObject
Protocol and marking that property as@Published
inside our Object.