55

I am currently writing Swift 3 code in Xcode 8.

When using oldValue and newValue default parameters inside the willSet and didSet blocks, I am getting "unresolved identifier" compiler error.

I have a very basic code as below

var vc:UIViewController? {
    willSet {
        print("Old value is \(oldValue)")
    }
    didSet(viewController) {
        print("New value is \(newValue)")
    }
}

Apple Documentation for Swift 3 still seems to support these feature. I hope I am not missing anything here?

pkamb
  • 33,281
  • 23
  • 160
  • 191
Adithya
  • 4,545
  • 3
  • 25
  • 28

6 Answers6

91

You can also use vc:

var vc:UIViewController? {
    willSet {
        print("New value is \(newValue) and old is \(vc)")
    }
    didSet {
        print("Old value is \(oldValue) and new is \(vc)")
    }
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
FranMowinckel
  • 4,233
  • 1
  • 30
  • 26
69

The special variable newValue only works within willSet, while oldValue only works within didSet.

The property as referenced by its name (in this example vc) is still bound to the old value within willSet and is bound to the new value within didSet.

Robin Stewart
  • 3,147
  • 20
  • 29
25
var vc:UIViewController? {
    willSet {
        print("New value is \(newValue)")
    }
    didSet {
        print("Old value is \(oldValue)")
    }
}
Nirav D
  • 71,513
  • 12
  • 161
  • 183
Dmytro Shvetsov
  • 946
  • 10
  • 13
  • 1
    Not entirely right, oldValue still seems to be unrecognized. Removing `viewController` parameter seems to make it work. – Adithya Sep 18 '16 at 15:24
  • Yes, sorry. I did not notice ur variable. – Dmytro Shvetsov Sep 18 '16 at 15:35
  • 2
    From your answer, I was able to deduce that `newValue` works within `willSet` and `oldValue` works for `didSet` block given there are no custom parameters. – Adithya Sep 18 '16 at 15:32
  • Incidentally, https://docs.swift.org/swift-book/LanguageGuide/Properties.html documents the default parameter names of `newValue` and `oldValue` for the `willSet` and `didSet` property observers, respectively. – Kurt Peek Feb 27 '19 at 22:02
16

It's important to know that the special variable newValue only works within willSet, while oldValue only works within didSet.

var vc: UIViewController? {
    willSet {
        // Here you can use vc as the old value since it's not changed yet
        print("New value is \(newValue)")
    }
    didSet {
        // Here you can use vc as the new value since it's already DID set
        print("Old value is \(oldValue)") 
    }
}
Wissa
  • 1,444
  • 20
  • 24
0

You didn't try to initialize the variable with a new object by which you can set your clojure:

var vc:UIViewController? = UIViewController(){
   willSet { 
       print("Old value is \(oldValue)")
   }
   didSet(viewController) {
       print("New value is \(newValue)")
   }
}
pirho
  • 11,565
  • 12
  • 43
  • 70
gomozor
  • 97
  • 6
-7

That's why we use NSKeyValueObservation to monitor class object