On Mar 24, 2010, at 23:42, Laurent Daudelin wrote:

> In the Preferences.nib file, the checkbox and the textfield are bound to the 
> defaults controller. So far, so good. In the application delegate's 
> applicationWillFinishLaunching:, they have those 2 lines:
> 
>       [self bind:SKTAppAutosavesPreferenceKey toObject:userDefaultsController 
> withKeyPath:[@"values." stringByAppendingString:SKTAppAutosavesPreferenceKey] 
> options:nil];
>       [self bind:SKTAppAutosavingDelayPreferenceKey 
> toObject:userDefaultsController withKeyPath:[@"values." 
> stringByAppendingString:SKTAppAutosavingDelayPreferenceKey] options:nil];
> 
> The app delegate, by binding these properties to the user defaults 
> controller, then has its setAutosaves: and setAutosaveDelay: methods called 
> each time the checkbox is toggled or the text field value is changed. How 
> does that work behind the scene? The user defaults controller of course has 
> the keys saved in the user preferences set in IB. Maybe it's late but I fail 
> to understand this.

The [NSObject bind:] method implements functionality that's useful as *part* of 
a custom bindings implementation. As it happens, the method is also usable in 
isolation as a sort of observation convenience method. (People sometimes call 
this usage a "binding" or a "one-way binding" though by itself it doesn't meet 
the requirements of a bindings implementation. But that's a different soapbox.)

Let's call the 1st parameter the "receiver key", the 2nd parameter the "target" 
object, and the 3rd parameter the "target key path".

What the method does, in essence, is to establish the receiver as a 
KVO-observer of the target object for the target key path. In addition, when a 
KVO notification arrives, if the receiver key is actually a KVC property of the 
receiver, it sets that property to the value that changed at the target 
object's target key path.

In other words, the receiver's property is made to track changes in the target 
property. In the above example, this makes the app delegate's property values 
follow the user defaults values.

It works just fine, but I think this use of the 'bind:' method is an abuse of 
the API, especially as there are at least 2 other simple ways of getting the 
same effect:

You could do the same thing yourself, by calling [userDefaultsController 
addObserver: self forKeyPath: ...] and providing an 
'observeValueForKeyPath:...' method to transfer the changed value to the 
observer's property.

You could also make the app delegate's properties be derived properties, having 
the app delegate getter retrieve the user interface controller values directly, 
and using the keyPathsForValuesAffecting<Key> mechanism to provide KVO 
compliance.


_______________________________________________

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