【问题标题】:Swift @Published causing didSet recursionSwift @Published 导致 didSet 递归
【发布时间】:2021-09-24 21:03:23
【问题描述】:

以下测试代码有什么问题?当我在字段中输入一个字符时,didSet 进入一个递归循环。如果删除了 inout + &,则代码按预期运行,每次击键都会触发 didSet。同样,如果我删除了@Published,但保留了 inout 并且 & 不会发生 didSet 递归。

我为什么要这样做?我有一个表单字段类型(一个 4 char 十六进制字段),它需要通用处理,然后重新编码回基本结构。因此,目的是将所有公共代码抽象为一个函数,该函数在 ModelView 区域中设置每个 var 后触发。此代码只是重现问题的最小示例。

看起来就像仅仅获取@published var 的地址会触发关联的didSet。对此的解释是使用 inout always 会重写目标 var,即使没有进行任何更改。

class A: ObservableObject
{
  @Published var publishedVar = "abc" {
    didSet {
      print("didSet Triggered")
      doNothing(commonText: &publishedVar)
    }
  }
  
  private func doNothing(commonText: inout String)
  {
  }

}

struct ContentView: View {
  @ObservedObject var a = A()
    var body: some View {
      TextField("dummy", text: $a.publishedVar)
    }
}

如果相关,这是在将 Catlina 作为 Mac 应用程序(不是 IOS 或模拟器)运行的 Mac 上运行的。 Xcode 版本 12.4 (12D4e)

好的,我已经尝试在接收器上完成阅读并尝试遵循建议(下面更新了 A 类),现在我发现它在 doNothing 函数中递归。看起来我缺少一些基本的东西 8-(

class A: ObservableObject
{
  var cancellable: AnyCancellable?
  @Published var publishedVar: String = "def"
  
  private func doNothing(commonText: inout String)
  {
    print("In doNothing \(commonText)")
  }

  init()
  {
    cancellable = $publishedVar.sink { value in
      self.doNothing(commonText: &self.publishedVar)
      print("saw sink \(value)")
    }
  }
}

【问题讨论】:

    标签: swift swiftui swiftui-form


    【解决方案1】:

    如果您想在 Published 变量更改时收到通知,则不应使用 didSet 而应使用 combine 并观察变量。

    I.E

    $publishedVar.sink {
        print("didSet Triggered")
        doNothing(commonText: &publishedVar)
    }...
    

    【讨论】:

    • 对Combine来说是非常的新手......您能否详细说明该行应该放在代码中的哪个位置?
    • 这将进入您的 class A 的初始化中。现在在移动设备上道歉,所以不容易更新我上面的例子。
    • 谢谢,如上所示更新了课程。现在在 doNothing 上递归。我是否正确地遵循了您的建议?
    • 我猜问题出在 inout 参数上。也许标记是 inout“设置”它所以会触发 didChange?不标记为inout的时候试试看是否有效
    • 是的,输入输出是问题所在。但是,如果提取的公共代码要可选地更新引用,则需要该地址。我在更新值时预期递归(需要)。引起我的 WT# 响应的是,仅引用地址而不进行任何分配会触发递归发生。
    猜你喜欢
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多