簡體   English   中英

屬性觀察者 willSet 和 didSet; 屬性獲取器和設置器

[英]Property observers willSet and didSet; Property getters and setters

在屬性中使用 this 時, willSet - didSetget - set有什么區別?

從我的角度來看,它們都可以為屬性設置值。 什么時候,為什么,我應該使用willSet - didSet ,什么時候get - set

我知道對於willSetdidSet ,結構如下所示:

var variable1 : Int = 0 {
    didSet {
        println (variable1)
    }
    willSet(newValue) {
    ..
    }
}

var variable2: Int {
    get {
        return variable2
    }
    set (newValue){
    }
}

何時以及為什么應該使用 willSet/didSet

  • willSet在值存儲之前被調用。
  • 在存儲新值立即調用didSet

考慮您的輸出示例:


var variable1 : Int = 0 {
        didSet{
            print("didSet called")
        }
        willSet(newValue){
            print("willSet called")
        }
    }

    print("we are going to add 3")

     variable1 = 3

    print("we added 3")

輸出:

we are going to add 3
willSet called
didSet called
we added 3

它像前置/后置條件一樣工作

另一方面,如果要添加例如只讀屬性,可以使用get

var value : Int {
 get {
    return 34
 }
}

print(value)

value = 2 // error: cannot assign to a get-only property 'value'

@Maxim 的答案是針對您問題的第一部分。

至於何時使用getset :何時需要計算屬性。 這個:

var x: Int

創建一個存儲屬性,它由一個變量自動備份(雖然不能直接訪問)。 為該屬性設置值被轉換為設置屬性中的值,並且類似地用於獲取。

反而:

var y = {
    get { return x + 5 }
    set { x = newValue - 5}
}

將創建一個不受變量支持的計算屬性 - 相反,您必須提供 getter 和/或 setter 的實現,通常從另一個屬性讀取和寫入值,更普遍的是作為計算的結果(因此計算的屬性名稱)

推薦閱讀: 屬性

注意:您的代碼:

var variable2: Int {
    get{
        return variable2
    }
    set (newValue){
    }
}

錯誤的,因為在get你試圖返回自己,這意味着遞歸調用get 事實上,編譯器會警告你一條消息,比如Attempting to access 'variable2' within its own getter

var variable1 : Int = 0 { //It's a store property
    didSet {
        print (variable1)
    }
    willSet(newValue) {
    ..
    }
}

var variable2: Int { //It's a Computed Proprties
    get {
        return variable2
    }
    set (newValue){
    }
}

有關Store 屬性和計算屬性的詳細信息
因此,當您嘗試在分配時將值分配給變量時,就會出現“didSet”和“willSet”的概念。 正如@Maxim 所說

  • willSet在值存儲之前被調用。
  • 在存儲新值立即調用didSet


'willSet' & 'didSet' 的例子:

class Number {
   var variable1 : Int = 0 {
        didSet{
            print("didSet called")
        }
        willSet(newValue){
            print("willSet called")
        }

    }
}
print("we are going to add 3")
Number().variable1 = 3
print("we added 3")

//o/p:
我們要添加 3
willSet 調用
didSet 調用
我們添加了 3

通常,當兩個屬性依賴時,使用“get”和“set”。 (它也用於協議這是不同的概念。)

“獲取”和“設置”的示例:

class EquilateralTriangle{
    var sideLength: Double = 0.0
    init(sideLength: Double){
        self.sideLength = sideLength
    }
    var perimeter: Double {
        get {
            return 3.0 * sideLength
        }
        set {
            sideLength = newValue / 3.0
        }
    }

}

var triangle = EquilateralTriangle(sideLength: 3.0)
print(triangle.perimeter) //o/p: 9.0
triangle.perimeter = 12.0
print(triangle.sideLength) //o/p: 4.0

設置

get set實際不存儲值計算屬性 相反,它們提供了一個 getter 和一個可選的 setter 來間接檢索和設置其他屬性和值

此外,您可以定義只讀計算屬性。 只讀計算屬性總是返回一個值,並且可以通過點語法訪問,但不能設置為不同的值

示例僅獲取屬性-

 var number: Double {
        return .pi*2
    }

willSet didSet

willSet didSet屬性觀察者

屬性觀察者觀察並響應屬性值的變化。 每次設置屬性值時都會調用屬性觀察器,即使新值與屬性的當前值相同。

  • willSet 在值存儲之前被調用。
  • 在存儲新值后立即調用 didSet。

例子 -

var score: Int = 0 {
    willSet(newScore) {
        print("willSet  score to \(newScore)")
    }
    didSet {
        print("didSet score to \(oldValue) new score is: \(score)")
    }
}
score = 10
//Output 
//willSet  score to 10
//didSet score to 0 new score is: 10

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html

設置

如果您想實現 gettable 和 settable 屬性,可以使用常規的get-and-set語法。 但是,如果您實現read-only屬性,則可以使用get語法。 使用setter ,您將獲得一個newValue屬性。

class GetterSetter {
    var theValue: Bool = false
    var property: Bool {
        get { return theValue }
        set {
            print("Value changed from \(theValue) to \(newValue)")
            theValue = newValue
        }
    }
}

let getterSetter = GetterSetter()
getterSetter.property = true
getterSetter.property

// PRINTS:
// Value changed from 'false' to 'true'

設置

didSet屬性觀察器用於在剛剛設置屬性時需要執行代碼的情況。 實現didSet你會得到oldValue來表示以前的值。

class DidSetter {
    var property: Float16 = -1.0 {
        didSet {
            print("Value changed from \(oldValue) to \(property)")
        }
    }
}

let didSetter = DidSetter()
didSetter.property = 5.0
didSetter.property

// PRINTS:
// Value changed from -1.0 to 5.0

將設置

willSet屬性觀察器用於我們需要在設置屬性之前執行代碼的情況。 實現willSet你會得到newValue來表示它將成為的新屬性值。

class WillSetter {
    var property: String = "NO" {
        willSet {
            print("Value changed from \(property) to \(newValue)")
        }
    }
}

let willSetter = WillSetter()
willSetter.property = "YES"
willSetter.property

// PRINTS:
// Value changed from NO to YES

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM