3

I'm very new at programming and I'm having trouble understanding these two property observers.

I'm currently building an app with a table view where date pickers are contained in the rows of it. In this case I have two date pickers. As you all know, date pickers take a big amount of height in cells, therefore you need to hide them. The following code takes care of it:

var isCheckInDatePickerShown: Bool = false {
    didSet{
        checkInDatePicker.isHidden = !isCheckInDatePickerShown
    }
}

var isCheckOutDatePickerShown: Bool = false {
    didSet{
        checkOutDatePicker.isHidden = !isCheckOutDatePickerShown
    }
}

I have a very basic knowledge of programming so I'm confused by the functionality of didSet. What would happen with a willSet?

Anh Pham
  • 2,108
  • 9
  • 18
  • 29

1 Answers1

4

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.

jlmurph
  • 1,050
  • 8
  • 17
  • Thank you! When I get rid of the didSet and the computer property for that variable ( Just for fun ), I get an error saying expected declaration! Why is that? Why can't I declare a bool value and then assign the inverse of that variable to checkInDatePicker.isHidden? –  Jul 11 '17 at 02:47
  • that's because as soon as you declare brackets alongside a property, the compiler expects either code (get set didSet or willSet) or somekind of return statement to be present. If you remove code inside the brackets, you need to delete the brackets entirely, and leave the compiler handle the computations on the variable. Placing brackets and making it a computed property is identical to telling the compiler that you're taking over the variable for it. Read the `Computed Properties` section of the link in my post, it explains the use-cases of the various computed variable structures. – jlmurph Jul 11 '17 at 02:50
  • I did remove the brackets for the property therefore its not declared as a computed property anymore. I have: var isCheckInDatePickerShown: Bool = false and on the second line: checkInDatePicker.isHidden = !isCheckInDatePickerShown. I still get expected declaration error for the second line –  Jul 11 '17 at 02:52
  • Are you still writing : `var isCheckInDatePickerShown: Bool = false { }` ? if not, i can't re-create that error, you'd have to show me the context you're using it in – jlmurph Jul 11 '17 at 03:00
  • No. Im using a datepicker in my table view cell to simply display the date on a label. checkInDatePicker is declared as a UIDatePicker for my outlets. Could it be that putleta expect functions to change their states? –  Jul 11 '17 at 03:10
  • this is wrong `print("This new value is: \(isCheckInDatePickerShown)")` should be `\(newValue)` – DanSkeel Aug 24 '20 at 09:21