I have trouble understanding Cocoa Bindings. Can someone explain me what this is all about, in an way that is humanly perceivable?
Bindings is a system for connecting your views to your controllers without writing a lot of glue code to make them explicitly talk to each other. All you have to do is set up properties in both classes* and hook up the binding in IB.
The traditional approach is that the view has one or more outlets to talk to the controller (the most generic examples being delegate
and target
) and the controller has outlets to talk to the views. When the controller updates the model, it sends (for example) [view modelChange:newModelObject]
. When the view wants to update the model, it sends some delegate message to its delegate (the controller), such as NSText's textDidChange:
.
With Bindings, all you have to do in code is implement properties on the view and properties on the controller, then expose one or more properties of the view as bindings*. Then you only need to hook up the binding. If it's a Cocoa class, this is cake: just set it up in IB. If it's a custom class of your own, you'll probably write the bind:toObject:withKeyPath:options:
message yourself (not much harder).
Let me restate that: With Bindings, your entire glue code (most of the time) is [view bind:@"viewProperty" toObject:self withKeyPath:@"controllerProperty.modelProperty" options:options];
in the controller. Everything else is handled by the Bindings and KVO systems behind the scenes, and by your properties' accessors.
The disadvantage is that you must strictly conform to Cocoa Bindings' requirements. These are simple, but a lot of older applications are designed in a way that doesn't fit Cocoa Bindings.
@property(copy)
, never @property(retain)
(because otherwise, you will find yourself retaining someone else's mutable string, which they will then mutate while you're holding it).model.foo = bar
) or by accessor messages ([model setFoo:bar]
), never by direct instance variable access. (Obvious exception for accessor methods themselves, if you've written your own, because they must access the instance variable directly.)There are two advantages:
bind::::
messages for the old view's properties. If, a couple of years down the road, you decide that your current view just can't scale to your application's forthcoming capabilities, this gives you the flexibility to rip it out and start afresh with the minimum of pain.*And, according to the documentation, implement a KVO observation method in the view class, but I've never actually had to do this. I filed a documentation bug.
Added 2009-03-07: Ah, found a citation. “NSView subclasses can expose additional key-value-coding/key-value-observing compliant properties as bindings by calling the class method exposeBinding: for each of the properties.” —NSKeyValueBindingCreation So you shouldn't need to implement a KVO observation method.