一个在 Swift 3.0 下关于 KVO 和 Cocoa Bindings 的坑

By on

前段时间好好的看了一下 Cocoa Bindings,然后做了一个最基本的 Demo:三个 NSSlider 控制一个 NSColorWell 的颜色变化。结果发现无论怎么拖动 slider 都无法改变 well 的颜色。代码如下:

var r: CGFloat = 0.0
var g: CGFloat = 0.0
var b: CGFloat = 0.0

dynamic var color: NSColor {
    return NSColor(srgbRed: r, green: g, blue: b, alpha: 1)
}

class func keyPathForValuesAffectingColor() -> Set<String> {
    return Set(["r", "g", "b"])
} 

今天有空的时候又重新研究了一下,发现 Swift 里面 KVO 有两个坑:

  1. 被观察的属性应该是 dynamic 的;
  2. keyPathForValuesAffecting<Key> 在 Swift 下面被改方法名了。

很好奇的是,第二点官方也没有说明,API docs 里面也是 no diff 的状态。

修改后代码如下:

dynamic var r: CGFloat = 0.0
dynamic var g: CGFloat = 0.0
dynamic var b: CGFloat = 0.0

dynamic var color: NSColor {
    return NSColor(srgbRed: r, green: g, blue: b, alpha: 1)
}

override class func keyPathsForValueAffectingValue(forKey key: String) -> Set<String> {
    guard key == "color" else {
        return Set()
    }
    return Set(["r", "g", "b"])
}