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 (Cocoa-dev@lists.apple.com)

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]

Reply via email to