如果我们想要它在之后执行一些额外的功能selected
属性设置完毕后,我们可以简单地重写以添加属性观察器:
override var selected: Bool {
didSet {
if self.selected {
// do something
}
}
}
Swift 5 的更新答案:
override var isSelected: Bool {
didSet {
if self.isSelected {
// do something
}
}
}
如果我们关心之前的值是多少selected
是,我们可以通过以下方式访问它oldValue
:
didSet {
if self.selected == oldValue {
return
}
// do something
}
Swift 5 的更新答案:
didSet {
if self.isSelected == oldValue {
return
}
// do something
}
别忘了,我们可以使用willSet
如果我们需要在值改变之前做一些事情也是如此。
我很好奇当我们有一个很大的类层次结构时会发生什么,每个类都添加自己的东西willSet
and didSet
属性观察者,所以我创建了以下测试:
class ClassA {
var _foo: Int = 0
var foo: Int {
set(newValue) {
println("Class A setting foo")
self._foo = newValue
}
get {
return self._foo
}
}
}
class ClassB: ClassA {
override var foo: Int {
willSet {
println("Class B will set foo")
}
didSet {
println("Class B did set foo")
}
}
}
class ClassC: ClassB {
override var foo: Int {
willSet {
println("Class C will set foo")
}
didSet {
println("Class C did set foo")
}
}
}
现在,如果我们创建一个对象ClassC
并设置其foo
财产:
var c: ClassC = ClassC()
c.foo = 42
我们得到以下输出:
Class C will set foo
Class B will set foo
Class A setting foo
Class B did set foo
Class C did set foo
因此,重要的是要注意一些事情......
- 一个儿童班的
willSet
叫做before它的父母的willSet
.
- 一个儿童班的
didSet
叫做after它的父母的didSet
.
- 为了添加属性观察者而创建覆盖does not替换父类中的所有属性观察器。
前两点有点道理。事实上,这使得房地产观察家更具吸引力。实际上,Swift 迫使我们以适当的方式在层次结构中上下移动,并将其很好地分成两个单独的方法。 Swift 还阻止我们(我相信)覆盖父类的属性,但仍然允许我们观察该属性的更改——这比 Objective-C 的方法要好得多。
但第三点可能是最重要的。小心——你很容易陷入巨大的等级制度之中didSet
and willSet
代码减慢了本来应该是一个相当快的过程:设置属性的值。