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

时间:2019-11-13 03:50:07

标签: ios swift xcode swiftui

在此示例中,当我在屏幕上拖动时,为什么LabelViewRepresentable在每次“ updateUIView”调用之前都被重新初始化?如果我将计数器设为@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)"
  }
}

1 个答案:

答案 0 :(得分:1)

当您查看有关EnvironmentObject的Apple文档时,您会发现:

  

动态视图属性,该属性使用由   祖先视图使可绑定的当前视图无效   对象更改。

这意味着每当一个EnvironmentObject更改时,依赖于它的所有视图都会重新初始化并重新绘制。

它与State略有不同,在Apple文档中描述如下:

  

给定类型的持久值,视图通过该值读取和   监视值。

当State更改时,视图将无法重新初始化,因为State值将被丢弃。受国家影响的部分将被重画。另一方面,视图的所有具有State值作为绑定传入的子代都将重新初始化。