On Feb 6, 2010, at 19:18, Roland King wrote:

> - (void)setBounds:(NSRect)aRect
> {
>    [self willChangeValueForKey:@"bounds"];
>    bounds = aRect;
>    [self didChangeValueForKey:@"bounds"];
>    NSString *rectAsString = NSStringFromRect(aRect);
>    [self setValue:rectAsString forKey:@"boundsAsString"]; 
> }
> 
> Assuming I don't cache the object in an instance variable in the class, 
> because in my case I don't really need to, I can calculate it on the fly and 
> do not expect that to be a performance issue, should the 
> willChangeValueForKey: and didChangeValueForKey: calls bracket the entire 
> method so the setters of the underlying attributes (the persistent ones) are 
> complete before the call to didChangeValueForKey:? My concern here is that 
> the didChangeValueForKey: method could trigger something to go read the 
> transient property, but if I've not set the underlying persistent properties 
> yet, it won't work. Or should you not nest like that and I should set the 
> persistent variables first, then call willChange.. and didChange... 
> afterwards with nothing between them? 

Invoke 'willChange...' before you modify anything that might affect the value 
of the "bounds" property, so that the KVO mechanism can capture the correct 
"old" value for observers that request it. (This rule can be broken if 
absolutely necessary, since an incorrect "old" value isn't usually fatal to 
observers.)

Invoke 'didChange...' after you modify all of the underlying values. At this 
point, the KVO mechanism captures the "new" value and issues the KVO 
notifications. (This rule can't be broken, because any changes past this point 
won't result in a KVO notification.)

> Other question is, why do we have to use the setValue:<value> forKey: instead 
> of just invoking [ self setBoundsAsString: ].

You don't, but the "boundsAsString" property exists only to serve this one 
getter/setter pair, so it's not really worth giving it its own getter/setter, 
and not having them reduces any future tendency to start treating it as an 
independent property, which would obviously mess up the "bounds" property.

Be careful, however, to make sure that your implementation of such custom 
properties is fully compatible with undo. In the above example, undo after 
changing "bounds" will restore both "bounds" and "boundsAsString", which may 
cause "boundsAsString" to get set multiple times. In more subtle scenarios that 
can cause some nasty confusion.


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to