@State 和@ObservedObject 有什么区别,它们都可以用来持久化状态吗?
What is the difference between @State and @ObservedObject, can they both be used to persist state?
当我用谷歌搜索 "State vs ObservedObject" 时,第一个 result 来自 Hacking with Swift,它说的是 @ObservedObject
:
This is very similar to @State except now we’re using an external reference type rather than a simple local property like a string or an integer.
我可以使用 @ObservedObject
创建持久状态吗?它是否像 @State
用于简单属性和 @ObservedObject
用于复杂对象 一样简单,还是有更多细微差别?
@ObservedObject
不持久状态
Can I use @ObservedObject
to create persisted state?
就其本身而言,您不能。 Apple documentation 对 @State
有这样的说法:
A persistent value of a given type, through which a view reads and monitors the value.
但是我发现 @ObservedObject
没有提到持久性,所以我构建了这个小演示来确认 @ObservedObject
不持久状态:
class Bar: ObservableObject {
@Published var value: Int
init(bar: Int) {
self.value = bar
}
}
struct ChildView: View {
let value: Int
@ObservedObject var bar: Bar = Bar(bar: 0)
var body: some View {
VStack(alignment: .trailing) {
Text("param value: \(value)")
Text("@ObservedObject bar: \(bar.value)")
Button("(child) bar.value++") {
self.bar.value += 1
}
}
}
}
struct ContentView: View {
@State var value = 0
var body: some View {
VStack {
Spacer()
Button("(parent) value++") {
self.value += 1
}
ChildView(value: value)
Spacer()
}
}
}
每当您单击 value++
按钮时,都会导致重新呈现 ChildView
,因为 value
属性 已更改。 当视图因 属性 更改而重新呈现时,@ObservedObject
会重置
相比之下,如果您将 @State
变量添加到 ChildView
,您会注意到它的值在 @ObservedObject
重置时不会重置。
使用持久状态 @ObservedObject
要使用 @ObservedObject
保持状态,请在父视图中使用 @State
实例化具体的 ObservableObject
。所以要修复前面的例子,会像这样:
struct ChildView: View {
let value: Int
@ObservedObject var bar: Bar // <-- passed in by parent view
var body: some View {
VStack(alignment: .trailing) {
Text("param value: \(value)")
Text("@ObservedObject bar: \(bar.value)")
Button("(child) bar.value++") {
self.bar.value += 1
}
}
}
}
struct ContentView: View {
@State var value = 0
@State var bar = Bar(bar: 0) // <-- The ObservableObject
var body: some View {
VStack {
Spacer()
Button("(parent) value++") {
self.value += 1
}
ChildView(value: value, bar: bar).id(1)
Spacer()
}
}
}
class Bar
的定义与第一个代码示例没有变化。现在我们看到即使 value
属性 发生变化,该值也不会重置:
当我用谷歌搜索 "State vs ObservedObject" 时,第一个 result 来自 Hacking with Swift,它说的是 @ObservedObject
:
This is very similar to @State except now we’re using an external reference type rather than a simple local property like a string or an integer.
我可以使用 @ObservedObject
创建持久状态吗?它是否像 @State
用于简单属性和 @ObservedObject
用于复杂对象 一样简单,还是有更多细微差别?
@ObservedObject
不持久状态
Can I use
@ObservedObject
to create persisted state?
就其本身而言,您不能。 Apple documentation 对 @State
有这样的说法:
A persistent value of a given type, through which a view reads and monitors the value.
但是我发现 @ObservedObject
没有提到持久性,所以我构建了这个小演示来确认 @ObservedObject
不持久状态:
class Bar: ObservableObject {
@Published var value: Int
init(bar: Int) {
self.value = bar
}
}
struct ChildView: View {
let value: Int
@ObservedObject var bar: Bar = Bar(bar: 0)
var body: some View {
VStack(alignment: .trailing) {
Text("param value: \(value)")
Text("@ObservedObject bar: \(bar.value)")
Button("(child) bar.value++") {
self.bar.value += 1
}
}
}
}
struct ContentView: View {
@State var value = 0
var body: some View {
VStack {
Spacer()
Button("(parent) value++") {
self.value += 1
}
ChildView(value: value)
Spacer()
}
}
}
每当您单击 value++
按钮时,都会导致重新呈现 ChildView
,因为 value
属性 已更改。 当视图因 属性 更改而重新呈现时,@ObservedObject
会重置
相比之下,如果您将 @State
变量添加到 ChildView
,您会注意到它的值在 @ObservedObject
重置时不会重置。
使用持久状态 @ObservedObject
要使用 @ObservedObject
保持状态,请在父视图中使用 @State
实例化具体的 ObservableObject
。所以要修复前面的例子,会像这样:
struct ChildView: View {
let value: Int
@ObservedObject var bar: Bar // <-- passed in by parent view
var body: some View {
VStack(alignment: .trailing) {
Text("param value: \(value)")
Text("@ObservedObject bar: \(bar.value)")
Button("(child) bar.value++") {
self.bar.value += 1
}
}
}
}
struct ContentView: View {
@State var value = 0
@State var bar = Bar(bar: 0) // <-- The ObservableObject
var body: some View {
VStack {
Spacer()
Button("(parent) value++") {
self.value += 1
}
ChildView(value: value, bar: bar).id(1)
Spacer()
}
}
}
class Bar
的定义与第一个代码示例没有变化。现在我们看到即使 value
属性 发生变化,该值也不会重置: