To prevent this behaviour, you could override setName: to only change the value when the pointers are not the same.

Kiel

On 09/07/2009, at 8:05 AM, Jerry Krinock wrote:

Why do I receive KVO notifications when a key is set to the same value that it already is?

This happens not only when the new and old values are -isEqual:, but when they are identically the same pointer. I can't think of any reason why anyone would want notification of a no-op.

I understand that it's easy enough to filter these out in my observer methods, but it's certainly a waste of CPU cycles. I wonder if maybe Apple calculated that, in their implementation, it is on average less CPU cycles for me to filter them out in the notifications I actually receive, as compared to Cocoa filtering all notifications before posting?

I presume that, for example, Cocoa's NSControl subclasses must all be checking for equality before redrawing in responding to a KVO notification?

Jerry Krinock

******* Console Output **********

[Session started at 2009-07-08 14:51:07 -0700.]
2009-07-08 14:51:07.678 KVO triggered by change:
{
  kind = 1;
  new = alpha;
  old = <null>;
}
2009-07-08 14:51:07.746 KVO triggered by change:
{
  kind = 1;
  new = beta;
  old = alpha;
}
2009-07-08 14:51:07.752 KVO triggered by change:
{
  kind = 1;
  new = beta;
  old = beta;
}
2009-07-08 14:51:07.760 KVO triggered by change:
{
  kind = 1;
  new = gamma;
  old = beta;
}
2009-07-08 14:51:07.761 KVO triggered by change:
{
  kind = 1;
  new = gamma;
  old = gamma;
}
2009-07-08 14:51:07.764 KVO triggered by change:
{
  kind = 1;
  new = delta;
  old = gamma;
}

The Debugger has exited with status 0.


******* Demo Code **********

#import <Cocoa/Cocoa.h>


@interface Foo : NSObject {
  NSString* name ;
}

@property (copy) NSString* name ;

@end

@implementation Foo

@synthesize name ;

@end


@interface Observer : NSObject {
  id observee ;
}

@property (retain) id observee ;

@end

@implementation Observer

@synthesize observee ;


- (id)initWithObservee:(id)observee_ {
  self = [super init] ;
  if (self != nil) {
      [self setObservee:observee_] ;
      [observee addObserver:self
                 forKeyPath:@"name"
                    options:(NSKeyValueObservingOptionOld
                             + NSKeyValueObservingOptionNew)
                    context:NULL] ;
  }
  return self ;
}


- (void)observeValueForKeyPath:(NSString *)keyPath
                    ofObject:(id)object
                      change:(NSDictionary *)change
                     context:(void *)context {
  NSLog(@"KVO triggered by change:\n%@", change) ;
}


- (void) dealloc {
  [observee removeObserver:self
                forKeyPath:@"name"] ;
  [observee release] ;

  [super dealloc] ;
}

@end


int main (int argc, const char * argv[]) {
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init] ;

  Foo* foo = [[Foo alloc] init] ;

  Observer* observer = [[Observer alloc] initWithObservee:foo] ;

  NSString* alpha = @"alpha" ;
  NSString* beta = @"beta" ;
  NSString* gamma = @"gamma" ;
  NSString* delta = @"delta" ;

  [foo setName:alpha] ;
  [foo setName:beta] ;
  [foo setName:beta] ;
  [foo setName:gamma] ;
  [foo setName:gamma] ;
  [foo setName:delta] ;

  [foo release] ;
  [observer release] ;

  [pool release] ;
}


_______________________________________________

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/kiel.gillard%40gmail.com

This email sent to kiel.gill...@gmail.com

_______________________________________________

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