简体   繁体   中英

What are the fundamental differences between set and didSet?

I understand that one is a setter and the other is a property observer. My question is how do they differ in behavior and when would you use one over the other. Don't they do pretty much the same thing? For example:

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

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

They do not do pretty much the same thing, on the contrary they have totally different purposes. The get and the set are used on computed properties. For instance, take this example structure that has no real use, but is a good demo.

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

So, as you can see, the variable number isn't a variable in the traditional sense, it is a computed property. So, when I call s.number I get the product of x and y. Also, you would use the set to change other variables (not the computed property itself) in the structure. So, I set x and y to different values based on the newValue . This idea of a computed property can be used in place of a function and I find is very useful in simplifying retrieval of data from a function. For instance, you could have a structure that has a distance in kilometers and you might want that in miles very frequently. So, you could create a computed property miles for miles that computes the number of kilometers with the get method, and changes the number of kilometers with the setter if a you set miles to in your program.


Now, for the didSet and willSet . You can use these to notify your structure of a value change. For instance, an 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

Notice how the didSet is actually on a variable that contains a value, that is, it is not a computed property. Also, I used a computed property average to get the average. Overall, I hope I cleared up your confusion regarding this very powerful aspect of Swift.

One more thing. :)

set {} is calling when you initialise value, but not disSet {}

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

produce "0" and "1" output.

But didSet not so.

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

have not call before you change value. Only "1" result will be printed, not "0" and "1"

It can be as useful, so bug source.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM