[英]Property observers willSet and didSet; Property getters and setters
在屬性中使用 this 時, willSet
- didSet
和get
- set
有什么區別?
從我的角度來看,它們都可以為屬性設置值。 什么時候,為什么,我應該使用willSet
- didSet
,什么時候get
- set
?
我知道對於willSet
和didSet
,結構如下所示:
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 的答案是針對您問題的第一部分。
至於何時使用get
和set
:何時需要計算屬性。 這個:
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' 的例子:
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
是屬性觀察者屬性觀察者觀察並響應屬性值的變化。 每次設置屬性值時都會調用屬性觀察器,即使新值與屬性的當前值相同。
例子 -
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
如果您想實現 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.