属性用例:
class MyClass {
// 存储属性
var age: Int = 0
var address: String = "" {
// 属性观察器
willSet {
print(newValue) // 新值
}
didSet {
print(oldValue) // 旧值
}
}
// 延迟存储属性
lazy var testAge: Int = {
return age + 18
}()
// 计算属性
var des: String {
// 一个get为只读,可省略
// get/set为读写
get {
return "我的年龄是\(age),地址是\(address)"
}
set {
}
}
}
存储属性
- 计算属性可用于类、结构体、枚举。存储属性只能用于类和结构体。
- 结构体实例如果被赋值给一个常量,则结构体的属性都不可修改,因为结构体是值类型。类是引用类型,修改属性实际修改的是实例的属性,不受此影响。
// 存储属性
var age: Int = 0
var address: String?
延迟存储属性
- 当第一次被调用的时候才会计算其初始值的属性。
- 必须定义为var,因为常量在构造完成之前必须初始化,而延迟存储属性的初始值可能在构造完成之后才得到。
什么时候使用延迟存储属性:
- 属性的值依赖于构造完成之后才知道影响值的外部因素。
- 当获得属性的初始值需要复杂的大量的计算的时候。
// 延迟存储属性
lazy var testAge: Int = {
return age + 18
}()
计算属性
提供一个getter和一个可选的setter。setter中有默认值newValue。
- 只读计算属性,只有getter,getter {}可以省略。
// 计算属性
var des: String {
// 一个get为只读,可省略
// get/set为读写
get {
return "我的年龄是\(age),地址是\(address)"
}
set {
}
}
属性观察器
var address: String = "" {
// 属性观察器
willSet {
print(newValue) // 新值
}
didSet {
print(oldValue) // 旧值
}
}
可添加属性观察器的属性:
- 除了延迟存储属性以外的其他存储属性
- 通过重写属性的方式为继承的属性(存储属性和计算属性)添加
不必为非重写的计算属性添加属性观察器,因为可以通过计算属性的setter来监控和响应值的变化。
- willSet新值被设置之前调用
- didSet新值被设置之后立即调用
willSet默认参数值为newValue,didSet默认参数值为oldValue。
父类的属性在子类的构造器中被赋值时,它在父类中的 willSet 和 didSet 观察器会被调用,随后才会调用子类的观察器。在父类初始化方法调用之前,子类给属性赋值时,观察器不会被调用。
如果将属性通过 in-out 方式传入函数,willSet 和 didSet 也会调用。这是因为 in-out 参数采用了拷入拷出模式:即在函数内部使用的是参数的 copy,函数结束后,又对参数重新赋值。
全局变量和局部变量
全局变量:在函数、方法、闭包、或者任何类型之外定义的变量。
局部变量:在函数、方法、闭包内部定义的变量。
全局变量都是延迟的,不用标记lazy。局部变量从不延迟计算。
类型属性
用于定义某个类型所有实例共享的数据。
延迟初始化,第一次访问才会被初始化,不用使用lazy
使用关键字 static 来定义类型属性。在为类定义计算型类型属性时,可以改用关键字 class 来支持子类对父类的实现进行重写。