/*
Property Observers 属性观察是 Swift 中一个很特殊的特性。
willset
didSet
*/
class MyClass {
var date : NSDate {
willSet{
let oldDate = date
let newDate = newValue
print("即将将日期从 \(oldDate) 设定到 \(newDate)")
}
didSet{
let oldDate = oldValue
let newDate = date
print("已经将日期从 \(oldDate) 设定到 \(newDate)")
}
}
init() {
date = NSDate()
}
}
/*
初始化方法对属性的设定,已经在 willSet 和 didSet 中对属性的再次设定都不会再次出发属性观察的调用,不然会造成死循环。
*/
/*
swift 中声明的属性包括存储属性和计算属性两种。
其中存储属性将会在内存中实际分配地址对属性进行存储。
而计算属性则不包括背后的存储,只是提供set和get两种方法。
在同一个类型中,属性观察和计算属性是不能同事共存的。
也就是说,现在一个属性定义中同时出现 set 和 willSet/didSet 是一件办不到的事情。
如果我们无法改动这个类,又想通过高属性观察做一些事情的话,可能需要自泪花这个类,并且重写它的属性。
重写的属性并不知道父类属性的具体情况,而只从父类属性中几成名字和类型,一次在子类的重载属性中我们是可以对父类的属性任意的添加属性观察的,而不用在意父类到底是存储属性还是计算属性
*/
class A {
var number: Int{
get{
print("get")
return 1
}
set {
print("set")
}
}
}
class B: A{
override var number: Int{
willSet{
print("willSet")
}
didSet{
print("didSet")
}
}
}
let b = B()
b.number = 0
// 输出 get willSet set didSet
/*
这里要注意的是 get 首先被调用了一次。这是因为我们实现了 didSet, didSet 中会用到 oldValue, 而这个值需要在整个 set 动作之前进行获取并存储代用,否则将无法确保正确性。如果我们不实现didSet 的话,这次 get 操作也将不存在
*/