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 protected])
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 [email protected]