For example, I'd like to call a method on a class instance that will add a willSet
to a property. I'd like to not have to specify the willSet
in the declaration of the property, since I'd need to add conditional logic within the observer, and it would be unnecessarily run for every other instance that hasn't had this method called.
Something like this:
var someProperty: Int
func someMethod() {
someProperty { // this is the syntax/ability I'm unsure about
willSet { ...add some behavior... }
}
...more stuff...
}
Property observers observe and respond to changes in a property’s value. Property observers are called every time a property’s value is set, even if the new value is the same as the property’s current value. You can add property observers to any stored properties you define, except for lazy stored properties.
All you do to give it a custom name is write the new name inside parenthesis after the willSet or didSet, somewhat similar to naming parameters in a normal function, though without type information since the type is already stated as part of the property’s definition. You do not have to define both property observers if you only need one.
While Swift’s built-in property observers only enable us to observe synchronous property changes, they can also be used to build asynchronous abstractions as well — such as Futures & Promises. What do you think? Do you currently use property observers to propagate value changes, or is it something you’ll try out?
Back in Objective-C, if you wanted to do any special handling for setting a property, you would have to override the setter, reimplement the actual value setting (that was originally done for you), and then add whatever you wanted to do besides that, like posting a notification of a change.
An observer can be added to a property declared in a superclass, but not in the same class or in a class extension. You cannot declare the same property in two places in a function. The best solution I can come up with is something like this, where you have an optional closure that you evaluate in the willSet, and you only assign something to that property when you want the observing behaviour.
maybe something like:
private var _willSetCallback: ((Int) -> (Bool))?
var someProperty: Int {
willSet {
if let optionalBool = _willSetCallback?(newValue) {
// do something
}
}
}
func someMethod() {
self._willSetCallback = { newValue in
return newValue > 0
}
}
It isn't especially elegant, but it might more-or-less handle the behaviour you desire?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With