What Is the Purpose of Willset and Didset in Swift

What is the purpose of willSet and didSet in Swift?

The point seems to be that sometimes, you need a property that has automatic storage and some behavior, for instance to notify other objects that the property just changed. When all you have is get/set, you need another field to hold the value. With willSet and didSet, you can take action when the value is modified without needing another field. For instance, in that example:

class Foo {
var myProperty: Int = 0 {
didSet {
print("The value of myProperty changed from \(oldValue) to \(myProperty)")
}
}
}

myProperty prints its old and new value every time it is modified. With just getters and setters, I would need this instead:

class Foo {
var myPropertyValue: Int = 0
var myProperty: Int {
get { return myPropertyValue }
set {
print("The value of myProperty changed from \(myPropertyValue) to \(newValue)")
myPropertyValue = newValue
}
}
}

So willSet and didSet represent an economy of a couple of lines, and less noise in the field list.

What is the use of observer property didSet and willSet in Swift language?

The main usage is to capture and escalate the old and new values of the variable. willSet captures the newValue to which the property, variable, is about to be set and didSet captures the oldValue.

They're extremely handy for setup and teardowns... e.g.

var fileHandle: FileHandle {
willSet{
otherClass.disableAccessTo(handle: newValue)
}
didSet{
otherClass.enableAccessTo(handle: self.fileHandle)
yetAnotherClass.archiveFile(handle: oldValue)
}
}

Property observers willSet and didSet; Property getters and setters

When and why should I use willSet/didSet

  • willSet is called just before the value is stored.
  • didSet is called immediately after the new value is stored.

Consider your example with outputs:


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")

Output:

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

it works like pre/post -condition

On the other hand, you can use get if you want to add, for example, a read-only property:

var value : Int {
get {
return 34
}
}

print(value)

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

When to use set vs willSet in Swift?

set and willSet have two completely different purposes.

set is used similarly to setter methods in other languages, thus the programmer clearly knows why and when he wants/needs to use it.

willSet is comparable to a trigger. So, whenever the value will be set - and this could be outside of the programmer's influence - this function will be called (except for initializers as stated in other answers).

Imagine a public class that you have created and that you offer to other programmers as part of your framework.
Within a willSet you could trigger other functions (e. g. writing a log entry with timestamp), whenever the value will be set. In addition it allows you to take any actions before the value is set, e.g. saving the old value to somewhere else before it gets overwritten.

Of course, you could do everything I described within the set function without using willSet.

But willSet and didSet give you the opportunity to write code which is better readable:

  • do whatever you you need to do prior to setting the value in willSet
  • set the value in set
  • do whatever you need to to after having set the value (e.g. logging or cleaning up) in didSet

Swift: Difference between KVO and willSet & didSet?

KVO is Objective C approach to observe properties is based on dynamic dispatch

While didSet/willSet are pure Swift methods which doesn't exist in ObjC

The latter in theory should be more efficient since Swift is trying to use static dispatch where possible for performance gains.

I'd go with ObjC approach only if you need compatibility with some ObjC dependencies or legacy code.

didSet vs willSet?

As Apple describes it:

You have the option to define either or both of these observers on a
property:

willSet is called just before the value is stored.

didSet is called immediately after the new value is stored.

So basically code performed in willSet will not have access to the newValue of the variable while it runs, whereas didSet will have access to it (since it's "after it's been set").

For :

var isCheckInDatePickerShown: Bool = false {
willSet{
print("This new value is: \(isCheckInDatePickerShown)")
}
}
var isCheckOutDatePickerShown: Bool = false {
didSet{
print("This new value after it was set is: \(isCheckOutDatePickerShown)")
}
}

if you call them:

print(isCheckInDatePickerShown)
.isCheckInDatePickerShown = true
print(isCheckInDatePickerShown)

Will print:

false

"This new value is: false"

true

print(isCheckOutDatePickerShown)
.isCheckOutDatePickerShown = true
print(isCheckOutDatePickerShown)

Will print:

false

"This new value after it was set is: true"

true

As you can see, the code ran in willSet did not yet have access to the new value, because it has yet to be committed to memory. Whereas didSet did have access to it.

What is the difference between `didset` and `willset` in swift?

willSet is executed before property is set.

didSet is executed after property is set.

How is didSet and willSet implemented in Swift

willSet/didSet and @objc dynamic are two different things.

  • willSet/didSet are lightweight Property Observers which are independent of KVO.
  • @objc dynamic exposes the property to Objective-C KVO. It's required for Cocoa Bindings


Related Topics



Leave a reply



Submit