【问题标题】:Swift property observer issueSwift 属性观察者问题
【发布时间】:2017-10-30 12:44:39
【问题描述】:

我的财产观察员有问题,想了解更多关于 Swift 行为的信息。

我有以下使用回调的架构:

更高级别的等级

class MyFirstClass : NSScrollView {

var colorDidUpdate: (() -> ())?

var color = NSColor.black {
  didSet { 
    colorDidUpdate?()
  }
 }


override init(frame frameRect: NSRect) {
    super.init(frame: frameRect)
    /* Some init */
    var mySecondClass = MySecondClass(frame: frame)
    colorDidUpdate = mySecondClass.enclosingViewDidUpdateColor
    mySecondClass.color = color
    documentView = mySecondClass
    /* Some other init */
  }

}

然后是第二类,它就像第一类和第三类之间的链接

class MySecondClass {
  var viewColorDidUpdate: (() -> ())?
  var color: NSColor?

  var myThirdClass = MyThirdClass(frame: frame)

  init(frame frameRect: NSRect) {
    /* Some init */
    viewColorDidUpdate = myThirdClass.updateColor
    myThirdClass.color = color
    /* Some other init */
  }

  func enclosingViewDidUpdateColor() {
    viewStyleDidUpdate?()
  }
}

最后是第三堂课。

class MyThirdClass {
  var color: NSColor?

  func draw(_ dirtyRect: NSRect) {
    guard let color = color else { return }
    // The color is black instead of green.
  }

  /* proerties and functions... */
  func updateColor() {
    functionThatWillTriggerTheDrawFunction() // Will trigger draw function
  }
}

如果我为 MyClass 属性设置新颜色,例如

var myClass = MyClass()
myClass.color = .green

打印的颜色不是“绿色”,但仍然是黑色...

我认为当我们在 didSet 范围内时,变量已经设置了,我错了吗?

我应该使用其他模式吗?

【问题讨论】:

  • "colorDidUpdate is aclosure used as a delegate",我认为对delegation存在误解...
  • @AhmadF 抱歉,我打错字了,我的意思是“用作回调”
  • @Hamish 我更新了我的问题的代码

标签: swift properties observable


【解决方案1】:

我认为当我们在 didSet 范围内时,变量已经设置了,我错了吗?

不是这样,但我猜还有其他事情发生(尽管似乎没有包含相关代码)

顾名思义,closure 会关闭它在定义时使用的变量。因此,您最有可能在您的颜色仍为 黑色时定义/使用闭包。您不能使用闭包为您提供捕获的变量的 current 值,但您可以将该值作为参数传递给闭包。我希望这是有道理的。

如果您提供更完整的代码示例,我可以更好地了解您的问题可能是什么。

更新(在您提供更多代码之后):

您只需要在它们的 init 方法中设置第二类和第三类的颜色。当您更新第一类颜色属性时,您永远不会更新它们的颜色属性。

我确信部分原因在于您提供的代码的简化,但您可能需要考虑一些事情以使事情更容易理解:

  • 尽量不要单独保存每个组件中的颜色,而是将其作为函数/方法的参数传递。这使得更容易看到正在发生的事情。例如,您可以调用您的更改处理程序colorDidUpdate(to color: NSColor) 并传入新值。这样,至少您的第二类不需要存储颜色,而是将其传递给updateColor(_ color: NSColor),这可以设置第三类的颜色属性并触发重绘。

  • 总的来说,我认为将任何更改传递给更改处理程序而不是从全局状态读取它是有益的。尽量不要存储所有内容,而是传递您需要的信息,而不是将其存储在两者之间(如果可能)。这样可以更轻松地查看数据和信息在您的应用中的流动位置和方式,并可能表明架构存在问题。

建议以不同的方式构建整个事物有点困难,因为这里的代码只是片段,但看起来你可以改进和简化一点。

【讨论】:

  • 感谢您的帮助,我更新了我的问题,以便您看到完整的架构。如果您需要更多,请随时告诉我。
  • 非常感谢您的更新,很抱歉刚刚回复,但我从未收到通知。我设法解决了这个问题,我为此感到很惭愧,确实第2和第3类的颜色没有在第1类颜色中设置...
  • 永远不要为您编写的代码感到羞耻!我们都去过那儿。说真的,从来没有人天生就写过很棒的代码。我在回答中写的东西并不普遍适用,在某些情况下可能是不好的建议。没有“完美的代码”!
猜你喜欢
  • 2016-04-22
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-02
相关资源
最近更新 更多