How can you set a property's value in Swift, without calling its didSet()
function outside of an initialization context? The code below was a failed experiment to achieve this within the classes' noside()
function
class Test
{
var toggle : Bool = 0
var hoodwink : Int = 0 {
didSet(hoodwink)
{
toggle = !toggle
}
}
// failed attempt to set without a side effect
func noside(newValue : Int)
{
hoodwink = newValue
println("hoodwink: \(hoodwink) state: \(toggle)")
}
func withside(newValue : Int)
{
self.hoodwink = newValue
println("hoodwink: \(hoodwink) state: \(toggle)")
}
}
It is quite trivial to do in Objective-C with auto-synthesized properties:
With side effect (if present in setter):
self.hoodwink = newValue;
Without side effect:
_hoodwink = newValue;
What you do in Objective-C to "avoid side effects" is accessing the backing store of the property - its instance variable, which is prefixed with underscore by default (you can change this using the
@synthesize
directive).However, it looks like Swift language designers took specific care to make it impossible to access the backing variables for properties: according to the book,
Of course this applies only to using the "regular language" means, as opposed to using reflection: it might provide a way around this restriction, at the expense of readability.
If you exactly know when you want to apply side effects just make it explicitly:
1 Solution:
2 Solution:
I think these solutions will be more clear and readable, then using one variable which at some calls should have side effects and shouldn't at others.
The issue I was trying to solve is I wanted to get a
doCommonUpdate
call when one value changed, or one if both changed at the same time. Doing this created a recursion because if either value changed it would calldidSet
each time. Example setup, mine was more involved:Note Wilma does not print because of the commented out lines.
My solution was to move all those variables into a separate struct. The this approach solves the problem and has the side benefit of creating a another grouping which helps meaning. We still get the
doCommonSetup
when either value changes independently and when we get both values changed at the same time.A possible hack around this is to provide a setter which bypasses your didSet
Ugly but workable