Swift10/90Days - 屬性

屬性

延時存儲屬性

Objective-C 的作法

有時候咱們須要延時加載屬性,在 Objective-C 中能夠經過重寫 getter 方法實現:html

@property (nonatomic, strong) NSMutableArray *players;

- (NSMutableArray *)players {
    if (!_players) {
        _players = [[NSMutableArray alloc] init];
    }
    return _players;
}

Swift 的新關鍵字

在 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"

References

相關文章
相關標籤/搜索