51

在属性中使用 this 时willSet-didSetget-有什么区别?set

从我的角度来看,它们都可以为属性设置值。什么时候,为什么,我应该使用willSet- didSet,什么时候get- set

我知道对于willSetand didSet,结构如下所示:

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

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

5 回答 5

51

何时以及为什么应该使用 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'
于 2014-08-20T07:25:43.377 回答
26

@Maxim 的答案是针对您问题的第一部分。

至于何时使用getand 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

于 2014-08-20T07:37:31.787 回答
4
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
于 2017-07-20T13:00:18.443 回答
3

设置

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

于 2017-12-06T09:29:14.083 回答
0

设置

get-and-set如果要实现 gettable 和 settable 属性,可以使用常规语法。get但是,如果您实现read-only属性,您可以只使用语法。与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
于 2020-12-04T00:28:05.487 回答