属性
存储属性
初始化的时候必须赋值
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 才能访问延迟存储属性
因为延迟属性初始化时需要改变结构体的内存