OK, I filed Bug ID# 7827354.  (See bottom of this message.)  But I don't see 
the need for MAKVONotificationCenter here...


On 2010 Apr 02, at 22:33, Kyle Sluder wrote:

> I would think that the "right" thing to do would be to subclass 
> NSArrayController and write a
> -canPerformFoo method.

Yes, so I went back and did it the "right" way.  To be general, I called it 
simply -(BOOL)hasSelection

> But you would need to self-observe the selection property,

Indeed, because of the bug in NSArrayController, this doesn't work:

+ (NSSet*)keyPathsForValuesAffectingHasSelection {
    return [NSSet setWithObject@"selection"] ;
}

> which is perilous because -removeObserver:forKeyPath: doesn't take a context 
> argument (another
> bug every Cocoa developer should file a duplicate of).  So you could use 
> MAKVONotificationCenter (or OFBinding, our analogue) to self-observe.

I already use MAKVONotificationCenter in this project, but I don't see the need 
for it here.  In the array controller's -dealloc,

    [self removeObserver:self 
              forKeyPath:@"selectedObjects"] ;

Why is that perilous?  (It seems to work.)

> Perhaps it would be easier to instead put the -canPerformFoo method on your 
> window controller.

I already have my own NSArrayController subclass for other reasons.


**************************************

Apple Bug ID# 7827354
Title: NSArrayController Observeable Methods Don't Do 
+keyPathsForValuesAffectingKey

Summary:  There are four methods which give the selection in some form, and 
they are all documented to be "observable using key-value observing".  However, 
none of them trigger change notifications when their name is returned in 
+keyPathsForValuesAffectingKey.

Steps to Reproduce:

1.  Require an instance variable which is a function of the current selection 
in an NSArrayController.  Here is a simple example:

// In @interface,

/*!
 @brief    Returns whether or not any content item in the receiver
 is selected.
@details  This property should be observeable using KVO.
*/
- (BOOL)hasSelection ;

// In @implementation,

+ (NSSet*)keyPathsForValuesAffectingHasSelection {
    return [NSSet setWithObjects:
        // Any one of the following should be sufficient.
        @"selection",
        @"selectedObjects",
        @"selectionIndex",
        @"selectionIndexes",
        nil] ;
}

- (BOOL)hasSelection {
    return ([[self selectedObjects] count] > 0) ;
}

2.  Bind some binding in a user-interface element, for example the 'enabled' 
binding of some button which requires a selection in the array controller, to 
the 'hasSelection' property.

3.  Build and run the project.

4.  Change the number of items selected in the array controller from 0 to some 
nonzero number, and vice versa.

Expected Results:

When the number of selected objects changes, the object observing 
'hasSelection' should invoke -hasSelection.

Actual Results:

-hasSelection does not get invoked.

Notes:

I am advised by Kyle Sluder that the bug underlying this bug is the bug that 
+keyPathsForValuesAffectingValueForKey relies on 
NSKeyValueObservingOptionPrior, and that NSArrayController doesn't support 
NSKeyValueObservingOptionPrior.  See discussion here:

http://lists.apple.com/archives/Cocoa-dev/2010/Apr/msg00088.html

You must read the entire thread because I originally discovered this problem 
indirectly, and we also hypothesized other causes which turned out to be wrong.






_______________________________________________

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