属性
- 定义:属性将值跟特定的类、结构体和枚举关联。
- 分类:存储属性、计算属性和类型属性。
存储属性
- 定义:就是存储在特定类或者结构体实例中的一个常量或者变量。
1. 可以在定义存储属性的时候指定默认值;
2. 可以在构造过程中设置或修改存储属性的值;
3. 可以在构造过程中修改常量存储属性的值;
4. 只能用于类和结构体。
struct PersonInfo {
let name: String
var age: Int
}
var per = PersonInfo(name: "zhangsan", age: 18)
print(per.name)
per.age = 22
print(per.age)
let person = PersonInfo(name: "wxx", age: 22)
person.age = 18
结构体属于值类型,常量结构体的存储属性不能被改变。
class Person {
var name: String?
var age: Int?
}
let person = Person()
person.age = 22
person.age = 18
print(person.age)
类是引用类型,依然能够改变实例的变量属性。
- 懒存储属性:当第一次被调用的时候才会计算其初始值的属性。
格式注意:
1. 在属性声明前使用 lazy 来标示一个懒存储属性;
2. 必须将懒存储属性声明成变量。
应用场景:
1. 属性初始值因为外部因素,在实例初始化完成之前不能确定;
2. 属性初始值需要复杂、大量的计算。
class DataImporter {
var fileName = "data.txt"
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
}
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
print(manager.importer.fileName)
计算属性
- 定义:不直接存储值,而是提供一个 getter 和一个可选的 setter,来间接获取和设置其他属性的值。
1. getter 使用 get 关键字进行定义;
2. setter 使用 set 关键字进行定义;
3. 可以用于类、结构体和枚举;
4. 如果计算属性的 setter 没有定义表示新值的参数名,则可以使用默认名称 newValue;
5. 只有 getter 没有 setter 的计算属性就是只读计算属性,且可以去掉 get 关键字;
6. 计算属性必须使用 var 关键字定义。
struct Point {
var x = 0.0
var y = 0.0
}
struct Size {
var width = 0.0
var height = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set(newCenter) {
origin.x = newCenter.x - (size.width / 2)
origin.y = newCenter.y - (size.height / 2)
}
}
var height: CGFloat {
return size.height * 2
}
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),
size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
属性观察器
1. 必须要声明清楚属性类型,否则编译器会报错;
2. willSet 可以带一个 newName 的参数,该参数默认命名为 newValue;
3. didSet 可以带一个 oldName 的参数,该参数默认命名为 newValue;
4. 即使设置的值和原来值是相同的,willSet 和 didSet 也会被调用;
5. 可以为除了懒存储属性之外的其他存储属性添加属性观察器。
class Person {
var name: String?
var age: Int = 0 {
willSet {
print("\(newValue)")
}
didSet {
print("\(oldValue)")
age = 9
}
}
}
let per = Person()
per.age = 8
print(per.age)
在 didSet 方法中再次对该属性赋值,这个值会替换观察器之前设置的新值。
class Person {
var name: String
var age: Int {
willSet {
print("\(newValue)")
}
didSet {
print("\(oldValue)")
age = 9
}
}
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let per = Person(name: "张三", age: 20)
print(per.age)
属性初始化时,willSet 和 didSet 不会被调用。