swift2 屬性

存儲屬性


struct FixedLengthRange {
    var firstValue: Int
    let length : Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0,length :3)
// 該區間表示整數0,1,2
rangeOfThreeItems.firstValue = 6
// 該區間現在表示整數6,7,8

可以在定義存儲屬性的時候指定默認值,也可以在構造過程中設置或修改存儲屬性的值,甚至修改常量存儲屬性的值


常量和存儲屬性


struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}

let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// 該區間表示整數0,1,2,3
rangeOfFourItems.firstValue = 6
// 儘管 firstValue 是個變量屬性,這裏還是會報錯

因爲rangeOfFourItems聲明成了常量(用let關鍵字),即使firstValue是一個變量屬性,也無法再修改它了。
這種行爲是由於結構體(struct)屬於值類型。當值類型的實例被聲明爲常量的時候,它的所有屬性也就成了常量。
屬於引用類型的類(class)則不一樣,把一個引用類型的實例賦給一個常量後,仍然可以修改實例的變量屬性。


延遲存儲屬性


延遲存儲屬性是指當第一次被調用的時候纔會計算其初始值的屬性。在屬性聲明前使用lazy來標示一個延遲存儲屬性。

class DataImporter {
    /*
    DataImporter 是一個將外部文件中的數據導入的類。
    這個類的初始化會消耗不少時間。
    */
    var fileName = "data.txt"
    // 這是提供數據導入功能
}

class DataManager {
    lazy var importer = DataImporter()
    var data = [String]()
    // 這是提供數據管理功能
}

let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// DataImporter 實例的 importer 屬性還沒有被創建

print(manager.importer.fileName)
// DataImporter 實例的 importer 屬性現在被創建了
// 輸出 "data.txt”



計算屬性


除存儲屬性外,類、結構體和枚舉可以定義計算屬性,計算屬性不直接存儲值,而是提供一個 getter 來獲取值,一個可選的 setter 來間接設置其他屬性或變量的值。

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)
        }
    }
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),
    size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// 輸出 "square.origin is now at (10.0, 10.0)”


如果計算屬性的 setter 沒有定義表示新值的參數名,則可以使用默認名稱newValue
struct AlternativeRect {
    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 {
        origin.x = newValue.x - (size.width / 2)
        origin.y = newValue.y - (size.height / 2)
    }
    }
}


只有 getter 沒有 setter 的計算屬性就是隻讀計算屬性。只
讀計算屬性總是返回一個值,可以通過點運算符訪問,但不能設置新的值。

struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// 輸出 "the volume of fourByFiveByTwo is 40.0"



屬性觀察器


可以爲除了延遲存儲屬性之外的其他存儲屬性添加屬性觀察器,也可以通過重載屬性的方式爲繼承的屬性(包括存儲屬性和計算屬性)添加屬性觀察器。
willSet觀察器會將新的屬性值作爲固定參數傳入,在willSet的實現代碼中可以爲這個參數指定一個名稱,如果不指定則參數仍然可用,這時使用默認名稱newValue表示。
類似地,didSet觀察器會將舊的屬性值作爲參數傳入,可以爲該參數命名或者使用默認參數名oldValue。

注: 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")
            }
        }
    }
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps


類型屬性

不管類型有多少個實例,這些屬性都只有唯一一份。這種屬性就是類型屬性。
用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
    }
}
print(SomeStructure.storedTypeProperty)
SomeStructure.storedTypeProperty = "Another value"
print(SomeStructure.storedTypeProperty)

print(SomeEnumeration.computedTypeProperty)
print(SomeClass.computedTypeProperty)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章