【问题标题】:SwiftUI Setting a State on initSwiftUI 在初始化时设置状态
【发布时间】:2021-09-29 12:45:25
【问题描述】:

如果我没有 @State 的初始值并将其设置在 init 中,我会收到致命错误:EXC_BAD_ACCESS,但仅限于发布模式

public struct TestSetStateView: View {
  @State var item:Int
  public init(item: Int) {
    self.item = item
  }
  public var body: some View {
    Text("Hello: \(item)")
  }
}

如果我添加一个默认值

public struct TestSetStateView: View {
  @State var item:Int = 0
  public init(item: Int) {
    self.item = item
  }
  public var body: some View {
    Text("Hello: \(item)")
  }
}

TestSetStateView(item: 8) 调用它会显示“Hello: 0”

如果我把它移到onAppear

public struct TestSetStateView: View {
  @State var item:Int = 0
  let firstItem: Int
  public init(item: Int) {
    firstItem = item
  }
  public var body: some View {
    Text("Hello: \(item)")
      .onAppear(perform: {
        item = firstItem
      })
  }
}

并使用TestSetStateView(item: 8) 调用它,它会显示“Hello: 8”,这很棒

或者如果我使用 _ 包装器:

public struct TestSetStateView: View {
  @State var item:Int
  public init(item: Int) {
    _item = State(initialValue: item)
  }
  public var body: some View {
    Text("Hello: \(item)")
  }
}

TestSetStateView(item: 8) 调用它会显示“Hello: 8”,这也很棒!

我只是不确定发生了什么,为什么我可以在onAppear 中使用item = firstItem 而不能在init 中使用。我有点理解 _ 使用 @State 包装器,但为什么我们不必使用 onAppear. 中的

【问题讨论】:

标签: swiftui state


【解决方案1】:

这段代码:

public struct TestSetStateView: View {
  @State var item:Int
  public init(item: Int) {
    _item = State(initialValue: item)
  }
  public var body: some View {
    Text("Hello: \(item)")
  }
}

是正确的。在初始化 State 变量之前,您不能直接设置基础值。请记住,State 是一个属性包装器。 @State var item 的类型不是 Int,它是一个恰好包含 IntState。它可以很容易地包含DoubleString。尝试将State 设置为Int 与设置StringInt 一样有意义。你有一个类型不匹配。坦率地说,编译器应该尖叫着说你不能这样做,但你却遇到了崩溃。

一旦State 变量被初始化,它就知道如何直接改变其底层包装值。你也可以直接在别处初始化它。甚至代码:_item 指的是包装的值,而不是状态本身。为什么他们在State 属性包装初始化程序中选择不同的语义,我不知道。但他们确实做到了,并排除了我们在我们的视图初始化中使用 @State 声明的便利 init()

【讨论】:

    猜你喜欢
    • 2019-09-02
    • 2020-05-07
    • 2019-08-24
    • 2019-10-30
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多