Why do I receive KVO notification when new value IS the old value?
Why do I receive KVO notification when new value IS the old value?
- Subject: Why do I receive KVO notification when new value IS the old value?
- From: Jerry Krinock <email@hidden>
- Date: Wed, 8 Jul 2009 15:05:29 -0700
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 (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