Re: bind:toObject:withKeyPath:options: Unidirectional or Bidirectional?
Re: bind:toObject:withKeyPath:options: Unidirectional or Bidirectional?
- Subject: Re: bind:toObject:withKeyPath:options: Unidirectional or Bidirectional?
- From: Keith Duncan <email@hidden>
- Date: Sat, 30 Jan 2010 13:15:45 +0000
> 1. The word "binding" is ambiguous. It refers on the one hand to the behavior of a class that allows it to synchronize some attribute (such as a property, but it could be something internal like an instance variable) to a property of target objects. It also refers on the other hand to the actual link from a specific instance of the class to a target object. This is the same sort of distinction as that between "class" and "object" (a type/token distinction, if you know that terminology), but there just aren't two words for it.
I think of it less in terms of synchronisation, and more in terms of dynamically rewriting the location of load/store operations at runtime.
> 2. A binding link is *always* bidirectional (unless its mis- or only partially implemented).
This isn't true, the directionality of a specific binding is documented per implementing class.
> 3. Binding behavior in each class is responsible for implementing the bidirectionality.
Correct.
> 4. Binding behavior implements the NSKeyValueBindingCreation protocol, which includes the 'bind:...' method. Invocation of that method is the mechanism by which a binding link is established. The method is *not necessarily*, by itself, the binding behavior. That's the essential point: the binding behavior is *more than* this one method.
Correct, an object being sent -bind:… can optionally register as an observer for the same key path.
>> "In its bind:toObject:withKeyPath:options: method an object must
>> as a minimum do the following:
>>
>> • Register as an observer of the keypath of the object to which
>> it is bound so that it receives notification of changes."
I half agree with this statement (even though it's from the documentation). As a controller telling another object to -bind:…, you don't care if it observes. However, you must maintain the observability contract; ensuring that if the receiver does decide to observe the key path, that the key path is KVO compliant.
An object deciding to observe the key path for a binding is an implementation detail. If an object doesn't maintain and present additional state, based on the current state of the binding, it doesn't need to observe it.
> (I don't know what happens if you specify a non-property name. Maybe an exception, or maybe nothing.)
-setValue:forKeyPath: allowing you to handle it in -setValue:forUndefinedKey:
Note that if you're using the NSObject implementation of -bind:…, internally there are invocations of -valueForKey: on the receiver of -bind:… too. So, your bound object needs to be fully KVC compliant for the key you're binding, this might mean implementing -valueForUndefinedKey: too.
> 7. NSObject provides no implementation of the rest of a binding's behavior, which is why there's a fair amount of code still to write for a custom binding behavior, even if NSObject's standard 'bind:...' implementation forms part of the custom behaviour.
Not strictly true, since the default implementation still stores the binding info allowing you to retrieve it using -infoForBinding:.
This allows you to override -bind:… and internally rewrite it to use the NSObject implementation but bind to a private and internal property. To set the value back you access the binding info stored for you by the default implementation.
You only really need to write a complete implementation of -bind:… if you need to store additional information, or customise the observation.
> 10. The reason one direction has a standard implementation in NSObject and the other direction doesn't is that the implementation of the first is typically abstractable, while the implementation of the second is class- and even binding-name-specific.
I've written an abstract implementation of the reverse direction.
In my extensions AFKeyValueBinding there are two useful methods, -valueForBinding: and -setValue:forBinding:, which introspect the -infoForBinding: dictionary, and send -valueForKeyPath: and -setValue:forKeyPath: respectively.
They also handle pushing the value through the value transformer identified by the NSValueTransformerBindingOption/NSValueTransformerNameBindingOption options.
> 11. A "Cocoa binding" is a custom binding implemented in the frameworks for most (NS) view and user interface objects, which extends basic binding behavior with additional functionality, such as special handling of NSController objects, and their pre-defined special keys, as binding link targets. This implementation is private and not available to the developers writing their own custom bindings (except, of course, to the extent it can be leveraged by subclassing).
Do you mean the NSEditor and NSEditorRegistration protocols? These are available for you to use in classes exposing their own bindings.
By the special keys do you mean the binding name strings, or the special values returned by them? The value markers are exported at the top of NSKeyValueBinding.h, and are determined using NSIsControllerMarker(). The default values for them can be returned by the NSPlaceholders protocol.
Keith
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden