Re: Why aren't my bindings firing?
Re: Why aren't my bindings firing?
- Subject: Re: Why aren't my bindings firing?
- From: Charles Srstka <email@hidden>
- Date: Sat, 28 Jun 2008 01:30:04 -0500
On Jun 28, 2008, at 1:00 AM, Ken Thomases wrote:
Actually, NSTextField does not have a binding named "stringValue",
even though it does have a property with that name. Conversely, it
has a binding called "value", although it doesn't have a property by
that name. See the NSTextField bindings reference: <http://developer.apple.com/documentation/Cocoa/Reference/CocoaBindingsRef/BindingsText/NSTextField.html
>.
What "has a binding called 'value'" means is described in that how-
it-works document. The NSTextField does use KVO to register itself
as an observer of the bound-to object and key path. However, what
it does with the notifications it receives because of that
observation is implementation dependent. In this case, if you think
of it as though it's keeping its stringValue property synced with
the property named by the key path you won't go too far wrong, but
that's because that's what NSTextField chooses to do with it. For
your own view class, you don't get that behavior automatically just
by calling bind:toObject:withKeyPath:options:. If that's the
behavior you want, you have to code it into your view class. In
your original post, you merely called
bind:toObject:withKeyPath:options: and expected the two properties
to be synchronized.
By the way, it's far from obvious that binding an NSTextField's
"value" binding corresponds to syncing its "stringValue" property
with some other object's property. Note that NSTextField also has
doubleValue, intValue, and floatValue properties, not to mention
tons of other more-obviously-unrelated properties. Also note that,
when you set up the value binding of an NSTextField (either in IB or
in code), there's no opportunity to specify which of these
properties is to be kept in sync. That should tell you that there
must be some other "smarts" (i.e. code) involved. KVC and KVO are
not sufficient, although they are involved.
Or that's what I thought it was, anyway. If Bindings don't do that,
then I'm a little confused as to what they actually *do*.
They are for keeping views and models in sync without a lot of glue
code.
Now, of course views have internal state (whether it's exposed as
properties or not). And models also have state (usually accessible
as properties). So, it's not surprising that your conception of
bindings is that they just keep those two pieces of state in sync.
However, note that a view's state may not have a direct mapping to a
model's state and vice versa. Bindings are more general than just
"connect this model property to that view property, and that's that".
Bindings allow you to keep a _conceptual_ attribute of the view
class in sync with the model. The binding name names the conceptual
attribute. For example, NSTextField offers to allow you to bind its
"value" -- which is a conceptual attribute which doesn't directly
correspond to any property -- to an object and key path. How it
maintains that "value" attribute in response to changes in the named
property is custom to NSTextField. It doesn't just magically fall
out of KVC and KVO.
If you want your class to support a binding, you have to 1) identify
the conceptual attribute available for binding, 2) pick a name for
that conceptual attribute (which is in a different namespace than
the class's properties, and so may or may not match one), and 3)
implement the custom logic for how to map from that conceptual
attribute to both the class's internal state and the bound property
of the other object.
Is that any clearer?
Hmm, you appear to be right. I'd forgotten that the text field's
actual binding was named "value". And no instance variable named
"value" appears to be implemented in NSTextField or any of its
superviews. Huh.
I guess the only question I still have then is: why did my example
worke one-way in the first place? If the bindings are in a different
namespace, shouldn't it have failed for lack of an exposed binding
named "title" in the Bar object? Or is there a *little* magic going on
here, just not going all the way?
I'd still prefer it if the system automatically provided support for
binding two properties to each other, for the cases where a property
*would* map one-to-one with the binding you wanted in the view (which
seems like it would have to happen quite frequently, especially for
the simpler bindings like font, color, enabled, etc.), while allowing
you to override that with custom code if needed. But at least now I'm
starting to feel like I'm beginning to understand how this thing
works, which is good. It's so frustrating when you're trying to work
with something that seems to be incomprehensible black magic.
Thanks,
Charles
_______________________________________________
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