I want to be able to change a (calendar) event, which has a startDate and an endDate. There’s also a duration.
- When the user changes the endDate, the duration is updated.
- When the user changes the startDate, the endDate changed according to the duration.
- When the user changes the duration, the endDate changes.
This last action would trigger the first action, which would trigger the third, which would trigger the first, ad infinitum (or when the stack fills up).
Lines like the following, to change the values, cause this loop:
[self setValue:[NSNumber numberWithLong:(interval%60)] forKeyPath:@"durationMinutes"];
[self setValue:ed forKeyPath:@"endDate"];
To simply stop observing, and restart after a change, is not attractive since the values in the GUI won’t get updated.
The question, then, is: How can I safely (and elegantly) update one of two interdependent properties?
You can bypass KVO notifications when necessary by using
setPrimitiveValue:forKey:. That sets the value but does not trigger any notifications. It also bypasses any custom setter you might have for the property. That should break the call cycle.When using this method you generally want to call the “will change” and “did change” methods to ensure that the Core Data state is maintained. That is, something like:
This avoids the need for a flag– you just say, hey, set the value and no messing around, OK?