Swift 属性观察器问题

标签 swift properties observable

我的属性观察器有问题,想了解更多关于 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 范围内时变量已经设置,我错了吗?

我应该使用其他模式吗?

最佳答案

I thought that when we were in the didSet scope the variable was already set, am I wrong?

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

顾名思义,闭包 会关闭它在定义时使用的变量。所以你很可能在你的颜色仍然黑色的时候定义/使用闭包。您不能使用闭包为您提供所捕获变量的当前 值,但您可以将该值作为参数传递到闭包中。我希望这是有道理的。

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

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

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

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

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

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

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

关于Swift 属性观察器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47015630/

相关文章:

java - 如何实现单次使用有序的ReplaySubject?

multithreading - 从后台线程 SWIFT 更新 UI

swift 4 : Detecting strongest frequency or presence of frequency in audio stream.

Swift 无法在类初始化方法中分配给自己

ios - 使用新属性扩展 UIView

properties - C++/CLI 速记属性

python - 是否可以在不需要重新定义属性的情况下覆盖父类(super class)的属性 setter

Angular 2 订阅值更改未反射(reflect)在 html 上

Swift 变量声明与可选(?)或强制解包(!)不同?

java - 使用参数中第一个 Observable 的结果将两个 Observable 与第二个 Observable 组合起来