Swift-----属性观察器(didSet、willSet)
应用场景一:保证对属性所赋动值是合法的,可以对不合法的数据进行处理。
class LightBulb { static let maxCurrent = 30 var current: Int = 0 { // 如果不设置newCurrent,默认可以使用newValue willSet(newCurrent) { print("Current value changed, the change is \(abs(newCurrent - current)).") } // 如果不定义oldCurrent,默认可以使用oldValue didSet(oldCurrent) { if current == LightBulb.maxCurrent { print("Pay attention, the current value get to the maxinum point.") } else if current > LightBulb.maxCurrent { print("Current too high, failing back to previous setting.") current = oldCurrent } print("The current is \(current).") } } } let bulb = LightBulb() bulb.current = 20 bulb.current = 30 bulb.current = 40
应用场景二:一个属性的值发生改变,其他会属性的值会跟着改变。
enum Theme {
case DayMode
case NightMode
}
class UI { var fontColor: UIColor! var backColor: UIColor! var theme: Theme { didSet { switch (theme) { case .DayMode: fontColor = UIColor.black backColor = UIColor.white case .NightMode: fontColor = UIColor.white backColor = UIColor.black } } } init(theme: Theme) { self.theme = theme } } let ui = UI(theme: .DayMode) ui.fontColor // nil ui.backColor // nil
执行完上面的代码会发现,fontColor和backColor都为nil。这是因为,在初始化函数init中不会调用didSet、willSet方法。故可以将上面的代码改为下面的代码。
class UI { var fontColor: UIColor! var backColor: UIColor! var theme: Theme { didSet { self.changeMode(theme: theme) } } init(theme: Theme) { self.theme = theme self.changeMode(theme: theme) } func changeMode(theme: Theme) { switch (theme) { case .DayMode: fontColor = UIColor.black backColor = UIColor.white case .NightMode: fontColor = UIColor.white backColor = UIColor.black } } } let ui = UI(theme: .DayMode) ui.fontColor ui.backColor