@State 和 @ObservedObject 有什么区别,它们都可以用来持久化状态吗? [英] What is the difference between @State and @ObservedObject, can they both be used to persist state?

查看:27
本文介绍了@State 和 @ObservedObject 有什么区别,它们都可以用来持久化状态吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在 Google 上搜索State vs ObservedObject"时,第一个

相反,如果您将 @State 变量添加到 ChildView,您会注意到它的值在 @ObservedObject> 被重置.

@ObservedObject 中使用持久化状态

要使用 @ObservedObject 保持状态,请在父视图中使用 @State 实例化具体的 ObservableObject.因此,要修复前面的示例,请执行以下操作:

struct ChildView:查看{让值:Int@ObservedObject var bar: Bar//<-- 由父视图传入var主体:一些视图{VStack(对齐:.trailing){Text("参数值:\(value)")Text("@ObservedObject bar: \(bar.value)")Button("(child) bar.value++") {self.bar.value += 1}}}}结构内容视图:查看{@State 变量值 = 0@State var bar = Bar(bar: 0)//<-- ObservableObjectvar主体:一些视图{虚拟堆栈{垫片()按钮((父)值++"){self.value += 1}ChildView(value: value, bar: bar).id(1)垫片()}}}

Bar 类的定义与第一个代码示例相同.现在我们看到即使 value 属性更改,该值也不会重置:

When I Googled "State vs ObservedObject" the first result was from Hacking with Swift and it said about @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.

Can I use @ObservedObject to create persisted state? Is it as simple as @State is for simple properties and @ObservedObject is for complex objects, or is there more nuance to it?

解决方案

@ObservedObject does not persist state

Can I use @ObservedObject to create persisted state?

On its own, you cannot. The Apple documentation has this to say about @State:

A persistent value of a given type, through which a view reads and monitors the value.

But I found no mention of persistence with @ObservedObject so I constructed this little demo which confirms that @ObservedObject does not persist state:

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()
    }
  }
}

Whenever you click on the value++ button, it results in a re-render of ChildView because the value property changed. When a view is re-rendered as a result of a property change, it's @ObservedObjects are reset

In contrast, if you add a @State variable to the ChildView you'll notice that it's value is not reset when the @ObservedObject is reset.

Using persisted state with @ObservedObject

To persist state with @ObservedObject, instantiate the concrete ObservableObject with @State in the parent view. So to fix the previous example, would go like this:

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()
    }
  }
}

The definition of the class Bar is unchanged from the first code example. And now we see that the value is not reset even when the value property changes:

这篇关于@State 和 @ObservedObject 有什么区别,它们都可以用来持久化状态吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆