有時候咱們須要延時加載屬性,在 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"