On Dec 12, 2009, at 11:03, Jim Majure wrote:
> I have a question regarding bindings: when I bind the value of a TableColumn
> to a controller, I specify the key path as something like this:
> @"arrangedObjects.name". So each row of the table, displays the "name" field
> from an object in the "arrangedObjects" property of the controller. In the IB
> it's actually broken into the controller key, "arrangedObjects", and the
> keypath, "name", though i don't see how this impacts the
> bind:toObject:withKeyPath:options: method.
>
> When I modify a value in a view, I send the setValue:forKey: message to the
> controller. What I don't understand is how the TableColumn is specifying the
> particular instance in the "arrangedObjects" array that was changed. If I
> just say this:
>
> [controller setValue:@"new value" forKey:@"arrangedObjects.name"]
>
> the specific instance is not specified. What is actually happening under the
> covers here?
>
> One possibility I can think of is that it uses the collection accessor
> pattern (objectIn<Key>AtIndex:) to retrieve the object, then use the
> setValue:forKey: on the individual object.
It's kind of mysterious, but I'm prepared to take some wild guesses hoping that
someone who knows more will jump in and correct/educate me.
There are a couple of pieces to consider:
1. While a table column represents an entire list of values, a NSTableColumn
really only represents a single value (via its single cell). It *appears* to
represent the entire list by representing different values at different times.
2. Bindings that we set in IB, such as NSTableColumn's "value" binding, are
what the documentation calls "Cocoa bindings", as opposed to just plain
"bindings". Presumably, all Cocoa bindings have the ability to recognize
certain predefined keys ("selection", "arrangedObjects", etc -- probably the
same list of keys that pops up at the controller key field in IB) as the first
component of the key path.
3. When sent to a NSArray, 'valueForKey:' returns an array of the values of the
key for each component element. [It's not clear whether NSTableColumn ever uses
this mechanism, though.]
4. When sent to a NSArray, 'setValue:forKey:' sets the value of each component
element to the same thing. [But it's unlikely this has any relevance to
NSTableColumn -- it's more relevant to changing multiple values displayed in
text fields, I think.]
So I suspect that NSTableColumn, via Cocoa bindings, decomposes the binding key
path into a reference to the NSArrayController and a model key, and effectively
does something like:
[[[controller valueForKey: @"arrangedObjects] objectAtIndex:
currentRow] setValue: newValue forKeyPath: @"name"];
It may do a similar thing for getting values, or it may make some use of #3
above. It must also (presumably) register as an observer of "arrangedObjects"
as well as the values of (some) individual objects, but it's not clear
precisely what the pattern of observers is.
Are you trying to bind Cocoa objects with Cocoa bindings, or do your objects
have a home-grown bindings implementation? If the latter, you might have a bit
of work to do, reinventing the Cocoa bindings behavior.
[I'll use this opportunity to get back on my soapbox and reiterate my opinion
that NSController and its demon offspring are truly horrible classes from the
developer's point of view. Their API behavior is no more and no less than
whatever behavior they happen to implement (in a properly designed class, the
implementation serves the API contract, not dominates it), and we're not told
what that behavior is, beyond a few vague generalities. We learn how to use
them by memorizing a few usage patterns that happen to work, and when we
overstep the bounds, things fail mysteriously, with at best a highly detailed
exception error message that is completely inscrutable.]
_______________________________________________
Cocoa-dev mailing list ([email protected])
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]