Re: Why doesn't -[NSArrayController selection] et al fire keyPathsForValuesAffectingKey?
Re: Why doesn't -[NSArrayController selection] et al fire keyPathsForValuesAffectingKey?
- Subject: Re: Why doesn't -[NSArrayController selection] et al fire keyPathsForValuesAffectingKey?
- From: Quincey Morris <email@hidden>
- Date: Fri, 2 Apr 2010 21:26:21 -0700
On Apr 2, 2010, at 20:25, Jerry Krinock wrote:
> Now, NSArrayController has five methods which give the selection in some form, and they are all documented to be "observable using key-value observing". So to make this work I implemented a +keyPathsForValuesAffectingSelectedFoo which returned the path to one of these keys, but when that didn't work I put in all five.
I only see 4 distinct keys in your list below, since one of them is duplicated.
> But I never could get it to work. By logging, I determined the problem: None of these five observers are firing the -selectedFoo getter when the array and table controller's selection changes. When I added, as a test, some other object's key path to keyPathsForValuesAffectingKey, and changed its value, the -selectedAgent method was invoked and updated the enabled state of my button as desired. So the problem seems to be that "observeable using key-value observing" doesn't mean what I think it means. Where am I going wrong?
I'm suspicious of the "fooArrayController" part. Is it *just* an instance variable? If so, then it gets to be a property only by virtue 'accessInstanceVariablesDirectly' being YES (which is bad magic, but a different story). If so, then it's not KVO compliant, though the only scenario I can think of where this would cause keyPathsForValuesAffecting... to fail is if something was already observing "selectedFoo" before the nib file containing it was loaded.
TBH, if I had a reason to want to observe the selection (keyPathsForValuesAffecting... being a special case of that), I'd create a real NSIndexSet* selectedItemIndexes property of my own, bind the array controller's "selectionIndexes" binding to that (so that the array controller maintains the real property for me), and then observe the real property, leaving all reference to the array controller itself out of my code.
> I solved the problem by eliminating all this code and binding my button's 'enabled' binding instead to the array controller's 'selection' and, to my surprise, it worked. My surprise is because, according to superclass NSObjectController documentation, 'selection' returns NSNoSelectionMarker when there is no selection, not nil which is what my NSIsNotNil value transformer would expect.
I think the answer is that it works because it's a frameworks binding, and frameworks bindings are very clever in ways we aren't actually told about. It probably knows whether it's allowed to pass on the marker value, or if it must convert the marker to some kind of "real" object first -- hence nil. Or perhaps passing NSNoSelectionMarker to the value transformer is simply special-cased somewhere.
_______________________________________________
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