Swift -- 属性

155 阅读2分钟

属性

存储属性

初始化的时候必须赋值

var age: Int = 10 var name: String?

计算属性

底层实际是方法 不占用 结构体或者类的内存 是指不占用内存空间,本质是set/get方法的属性

  • 计算属性不能使用 let 关键字
  • 计算属性(读、写): 不通过变量自己本身进行值的获取和存储,需要依赖其他变量来记录
  • 因此计算属性的作用是:用来间接获取/改变其他属性的值
  • 若获取或者存储值,可以使用属性观察器 (willSet\didSet)
//需要借助其他变量来记录,不能通过自己进行值的获取和存储
 var _tid: String?
 var tid: String? {
    set  {
        _tid = "tid\(newValue)"
    }
    get {
        return _tid
    }
}

//只读的话 可以只写 get 方法
var score: Int {
    get {
        return 100
    }
}

属性观察器

可以为非lazy的var存储属性设置属性观察器 (KVO)

struct Person {
    //结构体不用初始化,编译器会自动帮助我们合成初始化方法
    //若是 class 需要 var age: Int = 10
    var age: Int {
        willSet {
           print("will set an new value \(newValue) to age")
        }
        didSet {
            print("age has changed from \(oldValue) to \(age)")
            if age < 10 {
                age = 10
            }
        }
    }
    init() {
        self.age = 30
    }
}

// willSet 会传递新值,默认叫 newValue
// didSet  会传递旧值,默认叫 oldValue
// init 方法不会触发 willSet和 didSet

Tips

父类的属性在他自己的初始化器中赋值不会触发属性观察器,但在子类的初始化器中赋值会触发属性观察器

class Person {
    var age: Int {
        willSet {
            print("willset", newValue)
        }
        didSet {
            print("didset", oldValue, age)
        }
    }
    init() {
        self.age = 0
    }
}

class Student: Person {
    override init() {
        super.init()
        self.age = 1
    }
}

//willset 1
//didset 0 1
var stu = Student()

延迟存储属性 -- lazy

使用Lazy 定义一个延迟存储属性,当第一次用到属性时才会被初始化

let 必须在实例初始化方法完成之前就拥有值

延迟存储属性使用注意点

1、Lazy 在多线程下访问,并不是线程安全的,有可能被访问多次

2、当结构体包含一个延迟属性时,只有 var 才能访问延迟存储属性

因为延迟属性初始化时需要改变结构体的内存

截屏2021-06-13 下午11.31.08.png