Swift中的属性分为存储属性
和计算属性
。
存储属性会将常量和变量存储为实例的一部分。
计算属性则是返回一个计算后的值,而非存储的值。
计算属性可以用于类,结构体和枚举;存储属性只能用于类和结构体。
1. 存储属性
存储属性
定义在class
和struct
之中,是对象的数据成员的一部分,需要占据内存空间。
class
和struct
必须要提供初始化所有存储属性
的构造器。struct
会自动生成一个构造器;class
则必须手动实现。
struct FixedLengthRangeStruct {
var firstValue: Int // 变量
let length: Int // 常量
}
// struct 会自动生成为每个存储属性初始化的构造器
let obj1 : FixedLengthRangeStruct = FixedLengthRangeStruct(firstValue:12,length:12)
class FixedLengthRangeClass {
var firstValue: Int // 变量
let length: Int // 常量
init(){
firstValue = 13
length = 13
}
}
let obj2 = FixedLengthRangeClass()
1.1 定义存储属性时提供初始值
当为常量属性提供初始值时,构造器中不可以再重新赋值。
当为变量属性提供初始值时,构造器中仍可以再重新赋值
struct FixedLengthRangeStruct {
var firstValue: Int
let length: Int = 13
var strArray : [String] = []
}
// struct 会自动生成为每个存储属性初始化的构造器
let obj1 : FixedLengthRangeStruct = FixedLengthRangeStruct(firstValue:12)
class FixedLengthRangeClass {
var firstValue: Int // 变量
let length: Int // 常量
var strArray : [String] = []
init(){
firstValue = 13
length = 13
// 定义时提供初始值的属性不需要在构造器中再提供初始值
}
}
let obj2 = FixedLengthRangeClass()
1.2 延时加载存储属性
延时加载存储属性
是指当第一次被访问的时候才会计算其初始值的属性。
struct FixedLengthRangeStruct {
lazy var firstValue: Int = Int(15)
let length: Int = 13
}
延时加载属性必须声明为变量
延时加载属性必须提供初始化器
延迟加载属性不能保证线程安全
延时加载存储属性
在对象初始化之后,才会初始化。因此不可以声明为常量。同时必须在声明时提供一个初始化器。
延时加载存储属性
适用于一些需要较大开销才能够获得属性。因此将属性的初始化时机推迟到使用时。
1.3 常量结构体实例的存储属性
类或者结构体实例中的常量成员在初始化之后不可以再修改。
常量的结构体实例中的属性,无论是常量还是变量都不可以修改
常量的类实例中的变量属性可以修改
// 结构体
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
let obj1 : FixedLengthRange = FixedLengthRange(firstValue:12,length:13)
obj1.firstValue = 15 // 报错
// 类
class FixedLengthRange {
var firstValue: Int
let length: Int
init(){
firstValue = 15
length = 13
}
}
let obj2 : FixedLengthRange = FixedLengthRange()
obj2.firstValue = 15 // 可以重新赋值
2. 计算属性
计算属性
不同于存储属性
,不需要存储值,不会在对象实例中占据内存。通过提供setter,getter方法,来间接获取和设置其他属性或变量的值。
类
,结构体
以及枚举
都可以定义计算属性
。
计算属性必须使用var
声明
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, 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)
}
}
}
2.1 简化Setter和Getter声明
struct Rect {
var origin = Point()
var size = Size()
var center: Point {
get {
// 单行表达式可以参略return
Point(x: origin.x + (size.width / 2), y: origin.y + (size.height / 2))
}
set{
// setter可以不用提供新值的参数名,可以使用默认名称newValue
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
2.2 只读计算属性
只有 getter
没有 setter
的计算属性叫只读计算属性。
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
// 只读计算属性可以省略get{}
var volume: Double {
return width * height * depth
}
}
3. 存储属性和计算属性
计算属性
计算属性不需要存储值,但是需要提供setter和getter方法