有时候咱们须要延时加载属性,在 Objective-C 中能够经过重写 getter
方法实现:html
@property (nonatomic, strong) NSMutableArray *players; - (NSMutableArray *)players { if (!_players) { _players = [[NSMutableArray alloc] init]; } return _players; }
在 Swift 中用 lazy
标记便可,注意,必定要是 var
定义的变量才行,并且要是 class 或者 struct 的属性。注意,全局属性是不须要 lazy
标记的延时加载属性。若是须要延时加载,能够把延时加载的内容放在一个闭包里:ios
class PlayerManager { lazy var players: [String] = { var temporaryPlayers = [String]() temporaryPlayers.append("WHY") return temporaryPlayers }() } var p = PlayerManager() p // {nil} p.players p // {...}
什么时候该用延时加载这个功能呢?一个最典型的例子就是:当属性的初始化必须在对象初始化完成以后。swift
举个例子,我有个 Person 类,它有个 greeting
属性,返回打招呼时候的招呼用语。好比你叫汪海,那么它就是 "Hello, Wanghai"
。它的初始化依赖于当前对象的 name
值。这时可使用延时加载的特性:闭包
class Person { var name: String lazy var greeting: String = { [unowned self] in return "Hello, \(self.name)!" }() init(name: String) { self.name = name } } var p = Person(name: "WHY") p // {"WHY",nil} p.greeting p // {"WHY,{Some "Hello, WHY"}"}
还有种状况,就是运算量比较大的时候,能够用 lazy
避免没必要要的加载。app
计算属性和存储属性对应,不过它是经过 get
来获取值,经过一个可选的 set
方法来截取设值的状况。若是没有 setter
则该属性只读。经过一个 Time 类来演示计算属性的用法:atom
class Time { var seconds:Double = 0 init(seconds: Double) { self.seconds = seconds } var minutes: Double { get { return (seconds / 60) } set { self.seconds = (newValue * 60) } } } var time = Time(seconds: 120) time.minutes // 2 time.seconds // 120 time.minutes=20 // 20 time.seconds // 1200
能够看到,minutes 的值是基于 seconds 计算得到的。code
有时候在属性发生改动的时候
仍是上面那个 Person
类的例子,上次咱们用了延时加载,此次不妨用 didSet
实现,在设置 name
以后更新 greeting
的值:htm
class Person { var name: String? { didSet { self.greeting = "Hello, \(self.name!)" } } var greeting: String? } var p = Person() p.greeting // nil p.name = "WHY" p.greeting // "Hello, WHY"