我创建了一个这样的模型
import Foundation
class Play:ObservableObject{
@Published var name:String="Tayle"
@Published var age:Int=12
}
Run Code Online (Sandbox Code Playgroud)
它将在两个视图中使用
例如:
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")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行该项目时,他们有相同的行为。如果@StateObject可以做到,为什么还要选择@State
小智 17
@State是一个变量,用于保存值类型,例如布尔值、整数、字符串、结构体等。Apple 根本不打算用于@State诸如 之类的引用类型ObservableObjects,因为 State 再次意味着存储诸如 Int 之类的值类型,而不是类的实例。苹果在文档中表示,
\n\n不要\xe2\x80\x99t 使用状态属性进行持久存储,因为状态变量的生命周期反映了视图生命周期。相反,使用它们来管理仅影响用户界面的瞬态,例如按钮的突出显示状态、过滤器设置或当前选定的列表项。
\n
简而言之,您可以使用@State变量来存储用户单击按钮的次数(自应用程序启动以来),但不能存储另一个ObservableObject. 另外,如果您查看此文章,文章显示使用带有状态的对象不会导致视图的实际变量更新。这是因为,再次引用这篇文章,
\n\n因为我们\xe2\x80\x99使用的是复杂的引用类型,所以状态本身的值永远不会改变。虽然 state 的属性 num 已更改,但 @State 属性包装器不知道,因为它只监视变量状态,而不监视其任何属性。对于 SwiftUI 来说,因为它只是观察状态,所以它不知道 num 已经改变,所以永远不会重新渲染视图。
\n
@StateObject另一方面,An可以存储诸如 之类的东西ObservableObjects。当Object的值发生变化时,会引起视图更新,因为所有这些都被观察到SwiftUI。不过,这种情况只会发生在@Published属性上,并且这些属性的任何更改都将再次导致视图重新渲染。还有一个重要的注意事项:@StateObject每次视图出现时都会创建一个新实例。如果需要保留这些值,则需要从更根的视图传入对象。此外,@StateObject可以从视图外部更改 an ,而@State变量只能是私有的和本地的。有关原因的更多信息,请参阅 AppleState文档:https ://developer.apple.com/documentation/swiftui/state
资源:
\n对于对象,请使用@StateObject属性包装器。对于 String、Int 等,请使用@State属性包装器。
@State:当我们观察 ContentView 中存在的属性时,我们使用此属性包装器。
@StateObject:当我们观察 ContentView 外部(如对象中)的属性时,我们使用此属性包装器,我们可以通过首先使该类符合ObservableObject协议并将该属性标记为@Published对象内部来观察属性的变化。