瑞星 发表于 2024-6-15 01:54:54

【Swift】01-didSet、willSet、set、get的区别

前言

Swift 的属性分为:


[*]计算型属性
[*]存储型属性
存储型属性就是一般意义上明白的可以进行赋值和取值的变量。
var title = “学科”
计算型属性,字面意思为计算型的属性,这种属性没法存储值
一、 计算型属性

特征:仅有get(readOnly语义)或有get+set的属性是计算型属性,有get+set的属性仅作为其他属性的外部接口
注意:


[*]计算型属性自己不占用内存空间,所以不能赋值
[*]计算型属性自己不占用内存空间,所以不可赋值
get + set 为计算型属性的缘故原由:

真正赋值的过程是存在于 set 方法中并被底层包装掉的,如果我们手动实现了 set 方法,就无法进行正确赋值:
https://img-blog.csdnimg.cn/e48734c582314c4298d7f96a56af321b.png
xcode不建议各人直接在get方法中return返回当前属性,因为他会把当前属性画横线。

[*]计算属性有set时的get方法
https://img-blog.csdnimg.cn/f270e5c2f6c34f47baec6bd029a4a447.png
[*]计算属性有无set时的get方法
https://img-blog.csdnimg.cn/be935263637b4156854091268ebc4c7f.png
[*]计算属性有set,无get方法时:
https://img-blog.csdnimg.cn/62e4561ae3f64898a3cf9f4f29d2fc22.png
get + set 的正确使用方法:作为其他属性的外部接口

    // 私有属性,只能在当前类中访问
    private var _squre:Double = 0.0
    // 可以在任何地方调用
    var squre: Double {
      get {
            return _squre
      }
      set {
            if newValue <= 0 {
                print("newValue = \(newValue)")
            }else{
                _squre = newValue
            }
      }
    }

--------- 赋值 --------
let swiftRootVC = TestVC()
swiftRootVC.squre = 10
// 报错,错误信息为:'_squre' is inaccessible due to 'private' protection level
// swiftRootVC._squre = 10
self.navigationController?.pushViewController(swiftRootVC, animated:true)

--------- 调用 --------
    override func viewDidLoad() {
      super.viewDidLoad()

      print("_squre = \(_squre)")
    }
存储型属性

注意:初始化方法生成对象,并不会触发属性的 willSet didSet 方法。若想在初始化阶段触发 didSet,可以采用 KVC 的方式给对象初始化。
willSet


[*]willSet是一个属性观察器,用于在属性值将要被设置时实行一段代码。它是一个关键字,用于定义一个代码块,当属性值即将被设置时自动实行。
[*]willSet 能获取将要赋给属性的值 newValue
[*]操作的属性是对旧值操作,会被之后的内部 set 覆盖掉
[*]作用:观察
var name: String = "" {
    willSet(newName) {
      print("The name will be changed from \(name) to \(newName)")
    }
}
// 在上面的示例中,name属性被初始化为空字符串,定义了一个willSet代码块,它会在name属性的值将要被设置时打印一条消息。如果您稍后更改name的值,例如:
name = "John"
那么willSet代码块将自动实行,并打印出消息 “The name will be changed from to John”。
需要注意的是,willSet代码块只会在属性被设置时实行,如果您直接使用其存储来更改属性的值,willSet代码块将不会被实行。此外,willSet代码块中可以使用一个参数newName来访问即将被设置的新值。
didSet


[*]didSet是一个属性观测器,答应您观察和响应属性值的变化。它是一个关键字,用于定义每当属性值发生变化时自动实行的代码块.
[*]注意: didSet只有在通过赋值设置属性时才会实行。如果直接使用属性的存储更改属性的值,则不会实行didSet块。
[*]didSet 能获取属性之前的旧值 oldValue,新值即为属性
[*]操作属性是对新值进行操作
[*]作用:观察、数据加工
[*]当使用了 didSet 就不能再使用 set 了,因为 didSet 中已经包含了 set 状态
class TestVC {
// 注:class没有继承至ViewController

    init(squre: Double) {
      self.squre = squre
    }
    var squre: Double {
      willSet {
            print("willSet方法被调用")
            print("在willSet中,width = \(squre),newValue = \(newValue)")
      }
      
      didSet {
            print("didSet方法被调用")
            print("在didSet中,width = \(squre),oldValue = \(oldValue)")
      }
    }
}
初始化方法生成对象,并不会触发属性的 willSet didSet 方法:
// 初始化方法 没有触发 willSet didSet
let testSqure = TestVC.init(squre: 99.99)
// 打印99.99
print("testSqure = \(testSqure.squre)")
注意:

[*]有willSet\didSet不能写set、get
https://img-blog.csdnimg.cn/5b13a39b7e0043f6858c7fc0b0502b88.png
参考文献

: Swift5 didSet willSet set get
: Swift 计算属性、存储属性
2023年3月第一次编写
2023年3月28日,第二次编写

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【Swift】01-didSet、willSet、set、get的区别