Re: Basics of Cocoa Bindings
Re: Basics of Cocoa Bindings
- Subject: Re: Basics of Cocoa Bindings
- From: Quincey Morris <email@hidden>
- Date: Wed, 09 Sep 2015 08:48:22 +0000
(continued from part 1)
The clever thing about array controllers is that to metal pieces they look like plastic, and to plastic pieces they look like metal. Hence the name “mediating”. As in legal arbitration, the mediator looks to each side like the opposing side’s advocate. Their other generally useful characteristic is that IB recognizes them as “metal” targets for bindings, which is why array controllers tend to appear in those Bindings inspector popups (usually — there are exceptions to everything).
That’s what controllers are — adapters. They are a common generalization or abstraction that permits IB to connect pretty much any UI element indirectly to pretty much any model object. IB is so filled with admiration for them that it gives some of their standard properties (selection, arrangedObjects, etc) special placement in the Bindings inspector so that you can just choose the “controller key” from a menu without having to type it. There’s a whole digression possible here about the nature of these properties — some like “selection” are proxy objects, others like “selectedObjects” are true properties of the array controller — but I’m not going to digress. Controller keys are just preset initial components of a bindings component sequence. The rest of them are called “model keys”.
I don’t think you ever *need* an array controller, except perhaps where you need to get to a data model via a route that IB doesn’t recognize. Remember, to plastic, array controllers look like metal. You don’t actually *need* an array controller between a table view and a data model, but 99.9% of the time it’s easier just to go ahead stick one in the chain. Also, if you have multiple table views, you can connect them with array controllers into a single sequence that cascades the data out with no actual code.
Hmm, I just realized that what I said about table views is kind of old-school. It really only applies to cell-based table views. When it comes to view-based table views, I think I’ll just go ahead and risk offending the purists I haven’t offended yet by saying that binding view-based table view content *at all* is a waste of time, with or without an array controller. (By contrast, binding table cell subviews via the table cell view is absolutely the right thing to do.) Binding content is just awkward to do with view-based table views, and it saves you very little code. (It *may* eliminate the data source, but you must have a table view delegate anyway, and that’s where most of the code is.)
I was also going to talk a little bit about KVC and KVO, which is where you find topics like accessors, and the dreaded keyPathsForValuesAffecting<Key> (which is actually just a convenient shortcut to KVO compliance in some standard cases). In fact — er, here go the purists over the cliff again — bindings actually have very little to do with KVC, if you look at it right.
It’s true that, in practice, one of a binding’s two directions is always implemented using KVO. But you can treat this as an implementation detail and forget about it.
It’s also true that a requirement for bindings is that *every* component of the sequence of name strings (keys) *must* be a KVO-compliant property of the relevant object. That’s a draconian requirement or a natural outcome depending on your point of view. When you implement a data model for your app, you *should* IMO ensure that all of its properties are KVO-compliant just because it’s the right thing to do. For scalar (one-to-one, non-collection properties), it’s usually trivial. For one-to-many (collection) properties, it’s a few lines of boilerplate to implement a couple of accessor methods with predetermined names (usually just an insert accessor and a remove accessor).
If you follow this principle, then you can go hog wild binding things in your NIB files or storyboards, throwing in the occasional NSController to “metallicize” an attachment point that IB doesn’t otherwise recognize. (Incidentally, this is pretty much all that NSObjectController is good for. It has one other subtle but useful capability — it implements the NSEditor family of informal protocols — but other than that it’s pretty much dead weight.)
The only time you’d skip KVO compliance in a data model property is when the value changes outside your control, in a way that’s hard to monitor. If you can convince yourself you’ll never want to bind to, or observe, that property, go ahead and skip compliance. Otherwise, you’re going to save yourself grief later if you keep trying until you find a way of making it compliant.
I’ve gone on quite a long rant here, too long probably, though I tried to jettison every detail I felt I could do without. I hope it clarifies at least some things, without repeating a lot of things you already know. If there’s an executive summary, I guess I’d say it’s this: bindings, NSControllers and KVC/KVO are all core Cocoa competencies, but they’re three *separate* competencies. Not are all of equal depth. Switching metaphors, I’d say that bindings are pre-sliced bread, NSControllers are … I dunno … PopTarts, and KVC/KVO is French gourmet cooking.
If you try to conceptualize all of them as a single intertwined system, physiological damage may result. It should be possible to acquire competence in each somewhat separately, and then you’ll find some pleasure in joining them together in your own designs.
P.S. I see that Ken beat me to the posting punch. He’s given a different kind of answer to your question, and I hope both will be useful. I’ve tried to help you place yourself conceptually. When it comes to actually doing things, you can safely just do what Ken tell you to do. :)
_______________________________________________
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