Swift Properties
参考自苹果官网Swift文档 原文地址
类,枚举,结构体都具有属性
属性的种类,存储属性,计算属性,类型属性
- 存储属性
OC中的属性基本都可以称为存储属性,也是使用最广泛的属性,用于记录一个实例的属性的值 - 计算属性,下面是来自于官网的例子
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)
}
}
}
Rect 中的center 属性不存在于内存当中,每次获取这个center值走get方法 通过 origin 和 size 属性计算出来。同理,每次设置center 时也会通过set方法更新origin属性的值
不同于OC中的set,get方法,swift 的 set,get 方法用于计算属性的实现中,其中set方法不是必要的
- 类型属性
类似于OC 中的类方法,每个类,结构体,枚举都可以有自己的类属性。例如下面的 SomeStructure.computedTypeProperty。可以用于定义一些不需要实例化的属性。属性前用 static 修饰即为类属性。
struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 1
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 6
}
}
class SomeClass {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 27
}
class var overrideableComputedTypeProperty: Int {
return 107
}
}
属性的懒加载
OC 中一般使用重写get 方法来实现懒加载,Swift中需要在属性定义前加一个 lazy 关键字,例如
class DataManager {
lazy var importer = DataImporter()
}
DataManager 中的importer属性在最开始就 调用了DataImporter()初始化方法,但是关键字lazy 使其不会在一开始进入初始化方法,而是在首次调用importer 属性时才会进入初始化方法。
当然懒加载 lazy 关键字只用于 存储类型的属性
只读属性
OC 中的readonly 属性,在swift 中的写法如下
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}
}
直接大括号 return 掉
属性的监听
OC 中的经常重写set方法用于控制新的属性值,以及更新UI等,Swift 中可以通过实现属性的willset,didset 方法来实现,如下:
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) steps")
}
}
}
}
willSet 在属性totalSteps修改前调用
didSet 在修改后使用,如果didSet 后不加括号,则oldValue 为默认传入的旧属性值的字段。
注意:控制属性值的话需通过实现didset 方法,而不是willSet方法,例如:
var computeProperty :Int = 0{
didSet (oldCompute) {
print("old value \(oldCompute)")
if computeProperty > 10 {
computeProperty = 10
}
}
}
Swift中如果使用KVO,会显得有些奇怪。因为KVO 通过OC runtime实现,只支持NSObject 及其子类,所以如果要在Swift中使用,要在属性前加入 @objc dynamic 关键字。例如:
@objc dynamic var computeProperty :Int = 0{
}
属性的内存管理
同OC一样,如果要弱引用在属性前加 weak 关键字,如果是闭包需根据情况使用 unowned 关键字