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: Quincey Morris <email@hidden>
- Date: Sat, 30 Jan 2010 03:24:20 -0800
On Jan 29, 2010, at 22:52, Jerry Krinock wrote:
> In "Cocoa Bindings Programming Topics" ▸ "What Are Cocoa Bindings" ▸ "Supporting Technologies", I read:
>
> "A binding is established with a bind:toObject:withKeyPath:options:
> message which tells the receiver to keep its specified attribute
> synchronized ... with the value of the property... The receiver
> must watch for ... changes in the object to which it is bound and
> react to those changes. The receiver must also inform the object
> of changes to the bound attribute. ... There are therefore two
> aspects to keeping the model and views synchronized: responding
> to user interaction with views, and responding to changes in
> model values."
>
> This clearly states, twice, that ind:toObject:withKeyPath:options: creates something which is bidirectional.
>
> Then, in "Cocoa Bindings Programming Topics" ▸ "How Do Bindings Work" ▸ "BIndings in More Detail", I read:
>
> "In its bind:toObject:withKeyPath:options: method an object must
> as a minimum do the following:
>
> • Determine which binding is being set
> • Record what object it is being bound to using what keypath
> and with what options
> • Register as an observer of the keypath of the object to which
> it is bound so that it receives notification of changes."
>
> This tells me that, "as a minimum", a binding is only unidirectional.
>
> How do you know when a binding is going to be unidirectional or bidirectional, and how can you control this?
OK, so here's how I understand this (which may or may not be correct) ...
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.
2. A binding link is *always* bidirectional (unless its mis- or only partially implemented).
3. Binding behavior in each class is responsible for implementing the bidirectionality.
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.
5. The NSObject implementation of the 'bind:...' method does the minimum listed above, plus it causes the change notification to be handled, in the case where the binding name is actually a property name. In that case the attribute (a property) is updated to match the target object property. (I don't know what happens if you specify a non-property name. Maybe an exception, or maybe nothing.)
6. Therefore, NSObject's 'bind:...' method *in isolation* can serve as a one-way property synchronization link, which you may choose to call a "unidirectional binding", though I think it's a terrible mistake to think of it as any kind of binding.
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 behavior.
8. Therefore all of the documentation quoted above is correct. A binding [link] is established with a 'bind:...' message which [when sent] tells the receiver to keep its specified attribute synchronized [via its implementation of binding behavior] ... [The binding behavior of t]he receiver must watch for ...
9. The reason that the opposite direction of the binding link isn't "in" the 'bind:...' method is that this direction is triggered by actual attribute changes, not by KVO notifications (or, at least, not necessarily via the KVO mechanism -- remember that the attribute doesn't have to be an actual property). IIRC most of the additional crap you have to write to implement a custom binding [behavior] is related to detecting and processing these attribute changes.
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.
In short:
binding [link] != binding [behavior] != 'bind:...' method
For completeness, I would add:
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).
This claim about NSController objects is *entirely* my own speculation, based on eliminating other theories about how the documented Cocoa bindings behavior could possibly be implemented. I could be completely wrong about this.
Does that throw any light on the matter?
_______________________________________________
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