我的财产观察员存在问题,想了解更多有关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范围内时,变量已经设置好了,我错了吗?
我应该使用其他模式吗?
答案 0 :(得分:1)
我认为当我们在didSet范围内时,变量已经设置好了,我错了吗?
不,这是真的,但我想其他事情正在发生(虽然似乎没有包含相关代码)
顾名思义,closure
会关闭它在定义时使用的变量。因此,当您的颜色 黑色时,您最有可能定义/使用闭包。您不能使用闭包来为您提供捕获的变量的当前值,但您可以将该值作为参数传递给闭包。我希望这是有道理的。
如果您提供更完整的代码示例,我可以更好地了解您案例中的问题。
更新(在您提供更多代码后):
您只需在其init方法上设置第二和第三类的颜色。更新第一个类颜色属性时,永远不会更新它们的颜色属性。
我确信您所呈现的代码的简化部分归咎于责任,但您可能需要考虑一些事项以使事情更容易理解:
尽量不要单独保存每个组件中的颜色,而是将其作为函数/方法的参数传递。这使得更容易看到,发生了什么。例如,您可以调用更改处理程序colorDidUpdate(to color: NSColor)
并传入新值。这样,至少你的第二课不需要存储颜色,而是将其传递到updateColor(_ color: NSColor)
,这可以设置第三类'颜色属性并触发重绘。
一般来说,我认为将任何更改传递给更改处理程序而不是从全局状态读取它是有益的。尽量不要存储所有内容,而是传递所需的信息,而不将其存储在中间(如果可能)。这样可以更轻松地查看数据和信息在应用中的流动位置和方式,并可能表明架构存在问题。
建议对整个事物进行不同的构建有点困难,因为代码只是片段,但看起来你可以改进并简化一下。