Skip navigation.
 
mlKVC/KVO not working for a variable in custom view
FROM : Ken Tozier
DATE : Tue Jan 29 19:16:37 2008

Hi

I wrote a custom subclass of NSView that adds some behaviors I like 
all my views to have (subview dragging, subview selection management 
etc...) and am using it as a base class for many of my custom views. 
I ran into a KVC/KVO problem where a setter inside the view's 
mouseDown handler doesn't seem to post change notifications.

I tried using a setter method for the variable in question 
(clickCount) as well as using the manual willChangeValueForKey/
didChangeValueForKey combo but my observeValueForKeyPath is never 
getting called. I put a few NSLogs in the code to make sure the 
observers are getting registered and the setters are getting called 
(they are), but still no luck.

The class has other variables (not shown) which follow the same model 
for registration/setting and they all work perfectly. It's just this 
one variable that seems to be failing.

Anyone see why this might not be working?

Thanks for any help

Ken

Here's the relevant code
// Class definition
@interface PMView : NSView
{
   int                        clickCount;
   NSMutableArray            *children;
}

// Custom addSubview method
- (void) addSubview:(id) inView
{
   if ([children indexOfObject: inView] == NSNotFound)
   {
       [self addClickObserverForSubview: inView];
       
       [super addSubview: inView];
       [children addObject: inView];
   }

   // next two logs show that the views are getting added correctly
   NSLog(@"children: %@", children);
   NSLog(@"subviews: %@", [self subviews]);
}

// Convenience method
- (void) addClickObserverForSubview:(id) inSubview
{
   // next line prints to run log
   NSLog(@"adding click observer for: %@", inSubview);
   
   [inSubview addObserver: self
           forKeyPath: @"clickCount"
           options: NSKeyValueObservingOptionNew
           context: NULL];
}

// Change handler
- (void) observeValueForKeyPath:(NSString *) inKeyPath
           ofObject:(id) inObject
           change:(NSDictionary *) inChange
           context:(void *) inContext
{
   // Next line never prints to the run log on changes to the 
"clickCount" variable
   NSLog(@"Entered: PMView:observeValueForKeyPath: %@, object: %@, 
change: %@", inKeyPath, inObject, inChange);
}

// Setter method
- (void) setClickCount:(int) inCount
{
   // Next line prints to run log and inCount is valid
   NSLog(@"Entered: PMView:setClickCount with value: %i", inCount);

   clickCount = inCount;
}

// mouse down method
- (void) mouseDown:(NSEvent *) inEvent
{
   // next line prints to run log and values are correct
   NSLog(@"setting click count of: %@ to: %i", self, [inEvent 
clickCount]);
   
   // tried both of these methods for setting "clickCount"
   // but neither seems to trigger observeValueForKeyPath
   
   [self setClickCount: [inEvent clickCount]];    
   
   /*
   [self willChangeValueForKey: @"clickCount"];
   clickCount                = [inEvent clickCount];
   [self didChangeValueForKey: @"clickCount"];
   */
}

I also tried renaming the "clickCount" variable, in case there was a 
conflict, but that didn't work either

Related mailsAuthorDate
No related mails found.