set和didSet有什么根本区别?

时间:2015-10-12 23:45:45

标签: swift

我知道一个是一个二传手,另一个是属性观察者。我的问题是他们的行为有何不同,你何时会使用另一个。他们不是做同样的事情吗?例如:

var foo: String {
 set {
   run code when set
 }
}

var foo: String {
 didSet {
  run code when set
 }
}

2 个答案:

答案 0 :(得分:13)

他们并没有做同样的事情,相反他们有完全不同的目的。 getset用于计算属性。例如,采用这个没有实际用途的示例结构,但这是一个很好的演示。

struct test {
    var x = 5
    var y = 5
    var number: Int {
        get {
            return x * y
        }
        set (newValue){
            x = newValue / 2
            y = newValue / 2
        }
    }
}

var s = test()
s.number //25
s.number = 100
s.x //50
s.number //2500

因此,正如您所看到的,变量number不是传统意义上的变量,它是一个计算属性。所以,当我打电话给s.number时,我会得到x和y的乘积。此外,您将使用该集来更改结构中的其他变量(不是计算属性本身)。因此,我根据xynewValue设置为不同的值。这个计算属性的概念可以用来代替函数,我发现这对于简化从函数中检索数据非常有用。例如,你可以拥有一个以千米为单位的距离的结构,你可能会非常频繁地想要以英里为单位。因此,您可以为使用miles方法计算公里数的里程创建计算属性get,如果您在程序中设置里程,则可以使用setter更改公里数。< / p>

现在,对于didSetwillSet。您可以使用这些来通知您的结构值更改。例如,averageTracker。

struct averageTracker {
    var total: Double = 0 {
        didSet {
            numEntries++
        }
    }
    var numEntries: Double = 0
    var average: Double {
        get {
            return total / numEntries
        }
    }
}


var ave = averageTracker()
ave.total += 10
ave.total += 20
ave.average //15

注意didSet实际上是如何包含一个值的变量,也就是说,它不是一个计算属性。此外,我使用计算属性average来获得平均值。总的来说,我希望我能清除你对Swift非常强大的方面的困惑。

答案 1 :(得分:0)

还有一件事。 :)

set {} 会在您初始化值时调用,但不会调用 disSet {}

var x : Int = 0 {
  set {
    print(x)
  }
}
...
x = 1

产生“0”和“1”输出。

但确实不是这样。

var x : Int = 0 {
  didSet {
    print(x)
  }
}
...
x = 1

在更改值之前没有调用。 只打印“1”结果,不打印“0”和“1”

它可以是有用的,所以是错误源。