今天一哥们在群里问:"为什么我不能只重写 setter ,还要多写个 getter ?"
我一听也是懵了,后来在 playgroud 里面写,果然得到了一个错误:
class Person{
var labelText:String
{
set(newValue){
self.labelText = newValue
}
}
}
Variable With a setter must also have a getter
后来,查找 stackflow, 找到了答案:
一旦你给一个属性添加了 getter
或者 setter
,这个属性将变成 计算属性
.
后来,我在The Swift Programming Language 2.2
的 Properties 一章中,找到这样一段描述:
“In addition to stored properties, classes, structures, and enumerations can define computed properties, which do not actually store a value. Instead, they provide a getter and an optional setter to retrieve and set other properties and values indirectly.”
除了存储属性之外,类,结构体和枚举还可以定义计算属性,计算属性 不存储值 ,它们提供一个 getter
和一个 可选的 setter
,借此来读取和间接地设置其他属性和值.
我在文档中没有找到更多的说明,下面来说说我自己的思考:
计算属性不存储值,那么也就是说,只能我显式地告诉程序,这个值是怎么来的.所以,需要有一个
getter
,它是必须的,否则这个属性就不是计算属性.而是存储属性.setter
是可选的,可以不写 (不写setter
不写getter
,那么这个属性还是存储属性).但是一旦写了setter
(这个属性变成了计算属性),那么getter
也是必须的
willSet 和 didSet
刚刚说明了关于计算属性的一些特点,但是问题来了,我们经常有拦截setter
来做一些自定义处理的需求. 在 OC 中,这个很简单,重写 setter
方法就好了,但是, Swift 中, 添加setter
会让属性变味.
Swift 的设计者肯定也是考虑到了这一点,所以提供了 willSet
和 didSet
这两个属性观察方法.用法如下:
class Person{
var labelText:String = "great"
{
willSet{
print("labeltext will change!")
}
didSet{
print("labeltext did change!")
// labelText = "defalut"
}
}
}
输出结果:
labeltext will change!
labeltext did change!
11
这样,我们可以过滤值,可以自己处理一些事情,也不会误把存储属性转换成计算属性.