从 variable with a setter must also have a getter 引发的思考

今天一哥们在群里问:"为什么我不能只重写 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,借此来读取和间接地设置其他属性和值.

我在文档中没有找到更多的说明,下面来说说我自己的思考:

  1. 计算属性不存储值,那么也就是说,只能我显式地告诉程序,这个值是怎么来的.所以,需要有一个 getter ,它是必须的,否则这个属性就不是计算属性.而是存储属性.

  2. setter是可选的,可以不写 (不写 setter 不写 getter,那么这个属性还是存储属性).但是一旦写了setter(这个属性变成了计算属性),那么getter也是必须的

willSet 和 didSet

刚刚说明了关于计算属性的一些特点,但是问题来了,我们经常有拦截setter来做一些自定义处理的需求. 在 OC 中,这个很简单,重写 setter方法就好了,但是, Swift 中, 添加setter会让属性变味.

Swift 的设计者肯定也是考虑到了这一点,所以提供了 willSetdidSet这两个属性观察方法.用法如下:

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

这样,我们可以过滤值,可以自己处理一些事情,也不会误把存储属性转换成计算属性.

你可能感兴趣的:(从 variable with a setter must also have a getter 引发的思考)