为什么@EnvironmentObject强制重新初始化视图?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么@EnvironmentObject强制重新初始化视图?相关的知识,希望对你有一定的参考价值。

在此示例中,当我在屏幕上拖动时,为什么在每次“ updateUIView”调用之前都要重新初始化LabelViewRepresentable?如果我将计数器设为@State属性而不是@EnvironmentObject属性,则它只会初始化一次,就像我期望的那样。

import SwiftUI

class Counter: ObservableObject {
  @Published var count = 0
}

struct CounterView: View {
  @EnvironmentObject var counter: Counter

  var body: some View {
    LabelViewRepresentable(count: $counter.count)
      .gesture(DragGesture().onChanged({ _ in
        self.counter.count += 1
      }))
  }
}

struct LabelViewRepresentable: UIViewRepresentable {
  @Binding var count: Int
  private var view: UILabel

  init(count: Binding<Int>) {
    print("init")

    let label = UILabel()
    label.text = "0"
    self.view = label
    self._count = count
  }

  func makeUIView(context: UIViewRepresentableContext<LabelViewRepresentable>) -> UILabel {
    print("makeUIView")
    return view
  }

  func updateUIView(_ uiView: UILabel, context: UIViewRepresentableContext<LabelViewRepresentable>) {
    print("updateUIView")
    view.text = "(count)"
  }
}
答案

[当您查看有关EnvironmentObject的Apple文档时,您会发现:‘每当可绑定对象发生更改时,动态视图属性就会使用祖先视图提供的可绑定对象来使当前视图无效”这意味着,每次更改EnvironmentObject时,依赖于它的所有视图都会重新初始化并重新绘制。

它与State的工作原理略有不同,在Apple文档中,其描述如下:“给定类型的持久值,视图通过该值读取和监视该值。”当State更改时,视图将无法重新初始化,因为State值将被丢弃。受国家影响的部分将被重画。另一方面,具有State值作为绑定传入的视图的任何子级都将重新初始化。

以上是关于为什么@EnvironmentObject强制重新初始化视图?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 SwiftUI @main App 中的实例化不创建 EnvironmentObject?

使用 EnvironmentObject(按钮和导航视图)切换视图不起作用

SwiftUI @EnvironmentObject:未找到?

同一 EnvironmentObject 的多个实例

如何在 Angular 2 中强制组件重新渲染?

SwiftUI - 在 ObservableObject 类/依赖注入中使用 EnvironmentObject