gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Key Value Observation is over reacting


From: Markus Hitter
Subject: Re: Key Value Observation is over reacting
Date: Fri, 14 Dec 2007 13:15:39 +0100


Am 14.12.2007 um 10:37 schrieb Fred Kiefer:

-------- Original-Nachricht --------
Von: Markus Hitter <address@hidden>

I can't see when the getter method would
be used inside KVO at all. Notifications are sent on value changes
only, which does the setter. Where does the conflict arise?

It is when the KVO code tries to get the value for the key before the change (and also after, but it doesn't get that far). To get the value it uses the valueForKey: method and this fails with an unknown key (OK, the details are a bit more complex, but it boils down to this).

(see below)

Until today, I always thought KVO is based on a mini notification
center inside NSObject's -setValue:forKey:. This method would try a
few ways to get the variable set, then send a notification to all
subscribers on success. No need to patch existing classes.

This is only enough for changes done via the setValue:forKey: method, what about normal setter methods, the ones I have this issue with?

I must admit I thought observations work when using -setValue:forKey: only. So I put a small test app together to verify (whole Xcode 2.5 project attached):

- (void)doIt {
  // Different ways to count upwards.
  [self setValue:[NSNumber numberWithInt:1] forKey:@"value"];
  [self setValue:[NSNumber numberWithInt:2]];
  value = 3;
  NSLog(@"Part 1 done.");

  // Attempt to set the same value again.
  [self setValue:[NSNumber numberWithInt:3] forKey:@"value"];
  [self setValue:[NSNumber numberWithInt:3]];
  value = 3;

  return;
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
NSLog(@"Key path %@ set to %@", keyPath, [object valueForKeyPath:keyPath]);
  return;
}

which produces this output:

2007-12-14 12:56:05.299 KVOVerification[11246] Key path value set to 1
2007-12-14 12:56:05.302 KVOVerification[11246] Key path value set to 2
2007-12-14 12:56:05.304 KVOVerification[11246] Part 1 done.
2007-12-14 12:56:05.306 KVOVerification[11246] Key path value set to 3
2007-12-14 12:56:05.309 KVOVerification[11246] Key path value set to 3

So you're right, asking the setter method directly triggers an observation as well.

But as you see as well, setting a value to the same as before triggers notification as well, so it's still unclear, why you need to access the getter from inside the KVO mechanism. Just attempt to set the value, trust it to work and send out the notification.

Perhaps we should just replace them when they are actually being watched at least on one object?

I'd guess this would be more foolproof as there always arise unexpected situations where a catch-all mechanism gets to its limits. I'd expect an performance increase as well, as hooking up an observer is typically done once and for selected ivars only, while values are changed often and across the board.


Markus

Attachment: KVOVerification.tar.gz
Description: GNU Zip compressed data



- - - - - - - - - - - - - - - - - - -
Dipl. Ing. Markus Hitter
http://www.jump-ing.de/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]