Re: Why aren't my bindings firing?
Re: Why aren't my bindings firing?
- Subject: Re: Why aren't my bindings firing?
- From: Ken Thomases <email@hidden>
- Date: Sat, 28 Jun 2008 01:00:43 -0500
On Jun 27, 2008, at 11:08 PM, Charles Srstka wrote:
With that said, aren't bindings *always* creating a two-way
connection between properties?
Not exactly, no. A binding is a different thing than a property.
(By the way, did you read the "How Do Bindings Work?" chapter I linked
to, or the earlier thread?)
For example, say you have a generalized view like an NSTextField.
It's got a property called "stringValue" which is set via the -
stringValue and -setStringValue: methods. Sure, as a view, it's
rendering an object from my model on the screen, but at the same
time it's gotta store its data somewhere, because otherwise its
drawRect: method won't know what it should draw, and of course
NSTextField can't know about the objects in your model, because if
it did, then it wouldn't work with any other models and would lose
its generalization, working only with the specific model that
existed in your application. Now normally, an app would set the
NSTextField's "stringValue" property via the accessor methods, but
now Bindings present us with a new way to bind a property in the
model with the "stringValue" property in the NSTextField.
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?
Regards,
Ken
_______________________________________________
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