On Aug 2, 2009, at 18:07, Gregory Holden wrote:

1) NSArrayController and canRemove, how does it know?
A familiar example to those who ran through Aaron Hillegass' Learning Cocoa Programming.

I have an NSArrayController, an NSButton, and an NSTableView
- NSArrayController's contentArray is an NSMutableArray in a MyDocument class. - NSButton sends the action 'remove:' to the NSArrayController on click - The column in NSTableView has a binding to NSArrayController to display 'arrangedObjects.personName'

The last piece is the magical piece that is driving me nutty. The NSButton has a binding enabled = NSArrayController's -(BOOL)canEnable. I can't figure out how the NSArrayController knows when the NSTableView has a row selected.

Forget about the NSArrayController for a moment. The NSTableView has a "selectedIndexes" property which (in isolation) represents what rows are actually selected. It also has a "selectedIndexes" *binding*, which (when bound to another object) is automatically synchronized to the other object's idea of what the selection is. (That's what bindings are for, to synchronize properties between objects.) Depending on the application, this "other" object might be a controller (such as a NSWindowController) or the data model itself. (Imagine, for example, an application that wanted to save the selection in the document file -- the selection would be an attribute of the data model. Or imagine, for example, an application with multiple windows per document, each of which may have its own selection -- the selection would likely be an attribute of the NSWindowController.)

Now consider the NSArrayController. It's what's known as an "mediating" controller -- that is, it links a "coordinating" controller (such as a NSWindowController, or a NSViewController, or a NSDocument) to a view object, providing additional services. (For example, it provides the ability to sort and filter the data model from the view's perspective.) One of its mediating services is to synchronize the view's selection with the "coordinating" controller's idea of what the selection is. So now we have the selection in 3 places: the view, the mediating controller, and the coordinating controller or data model.

So the short answer to your question is: The NSArrayController knows what the NSTableView has selected via the table view's "selectedIndexes" binding, which operates automatically (though not magically).

2) requires 'insertObject:in<key>AtIndex' for 'removeObjectFrom<key>AtIndex' to work If I don't implement 'insertObject:in<key>AtIndex' then 'removeObjectFrom<key>AtIndex' is never called. Why? The only reason I can come up with is possibly a shortcut in Cocoa that if insert is not implemented then remove probably isn't either. Which bring me to my next question, how does it know the insert is implemented?
I overrode:
-(BOOL)respondsToSelector:(SEL)aSelector
but it never queries for the insert.  What magic does it work with?

It is merely the definition of "KVC compliance" that an object with an array property should implement *both* 'insertObject:in<key>AtIndex' and 'removeObjectFrom<key>AtIndex'. (Actually, there are two possible "insert" methods, and two possible "remove" methods, one of each of which must be implemented.) Without them both, the object is not KVC-compliant, and the lone implemented method is never called.

It's certainly possible that KVC doesn't use "respondsToSelector:" to determine compliance. The are Objective-C runtime functions it can call directly to find out the same information. How it finds out is an implementation detail that we don't really need to know, though it of course isn't magic either.

(I'd guess it doesn't call "respondsToSelector:" because it wants to ensure that the "insert" and "remove" methods are both implemented in the same class, and neither is inherited from a superclass. But that's pure speculation, and could easily be false. I don't know how or why it's implemented the way it is.)

HTH


_______________________________________________

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 arch...@mail-archive.com

Reply via email to