5
var userState: UserState {
    get {
        return userState
    }
    set {
        print("\(self.userState)")
    }
}

Returning userState causes an infinite loop. I'm not interested in the getter method and just want to return the value of the property in the getter. I would rather like to customise the setter method.

user1898829
  • 3,437
  • 6
  • 34
  • 62
  • 3
    The answer depends on what you plan to do in the setter. Show your actual setter. – rmaddy Mar 03 '17 at 16:08
  • 1
    What is it you are intending to accomplish? – fguchelaar Mar 03 '17 at 16:09
  • If you absolutely need to override `set` and `get`, keep `userState` public and create a private store `_userState` which the getter and setter read from. – JAL Mar 03 '17 at 16:11

2 Answers2

8

If you would like to override a setter, but keep your property readable, then you need to make a variable to "back" the property:

private var storedUserState: UserState
var userState: UserState {
    get {
        return storedUserState
    }
    set {
        print("Before: \(self.storedUserState)")
        storedUserState = newValue
        print("After: \(self.storedUserState)")
    }
}

If you would like to customize a setter method, but would prefer the property to remain stored, use property observers instead of overriding the accessors:

var userState: UserState = nil {
    willSet(newState) {
        print("About to set userState: \(newState)")
    }
    didSet {
        print("Finished: new=\(userState), old=\(oldValue)")
    }
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Ohh boy, this contrast is sooo great. I was always confused about these two. @others: the first way is also known as **computed** property – mfaani Mar 03 '17 at 16:34
  • @Honey I mean, let others use expressions like `if (obj.userState.someField > someValue)`, i.e. providing a getter that returns something useful. Another alternative is to let property getter throw an exception, creating an effectively "write-only" property (not a very good idea; one should go with a method at that point). – Sergey Kalinichenko Mar 03 '17 at 16:46
  • "property getter throw an exception, creating an effectively "write-only" property" you mean the `get` would look like: `get { fatalError()}` really don't understand where that could be used – mfaani Mar 03 '17 at 16:51
  • 1
    @Honey Yes, something like this: `user.password = "12345"` instead of `user.setPassword("12345")` You don't want an ability to write `"password: \(user.password)"` – Sergey Kalinichenko Mar 03 '17 at 16:51
3

Instead of set, what you want is willSet or didSet, which get run before/after the value changes. Then you can omit get.

With willSet, since the variable hasn't changed yet, the new value is available in a parameter called newValue. Conversely, didSet has oldValue.

Uncommon
  • 3,323
  • 2
  • 18
  • 36