4

I'd like to use KVO to observe changes to a value in an NSMutableDictionary. However, I'm finding that it's not working because the key in the dictionary that I'd like to observe contains dots.

What is the correct way to add an observer for a key path that contains dots?

For example, the solution to this question works fine:

@interface Foo : NSObject @end
@implementation Foo

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    NSLog(@"observing: -[%@ %@]", object, keyPath);
    NSLog(@"change: %@", change);
}

@end

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

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

    NSMutableDictionary * d = [NSMutableDictionary dictionary];
    [d addObserver:f forKeyPath:@"foo" options:0 context:NULL];
    [d setObject:@"bar" forKey:@"foo"];
    [d removeObjectForKey:@"foo"];
    [d removeObserver:f forKeyPath:@"foo"];
    [f release];

    [pool drain];
    return 0;
}

However, this does not work:

@interface Foo : NSObject @end
@implementation Foo

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    NSLog(@"observing: -[%@ %@]", object, keyPath);
    NSLog(@"change: %@", change);
}

@end

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

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

    NSMutableDictionary * d = [NSMutableDictionary dictionary];
    [d addObserver:f forKeyPath:@"com.company.foo" options:0 context:NULL];
    [d setObject:@"bar" forKey:@"com.company.foo"];
    [d removeObjectForKey:@"com.company.foo"];
    [d removeObserver:f forKeyPath:@"com.company.foo"];
    [f release];

    [pool drain];
    return 0;
}
Community
  • 1
  • 1
derekvanvliet
  • 679
  • 8
  • 17
  • Seems to me like this is is a tough one. Maybe the cheap way out would be replacing dots for something else when setting, getting and observing values in the dictionary. – Merlevede Feb 07 '14 at 15:39
  • @Merlevede that does resolve the problem I'm having, but I would consider that a last resort in my case. It would be a lot easier if there's a way to observe keys in a dictionary that contain dots. – derekvanvliet Feb 07 '14 at 15:56
  • 3
    As the [KVC Guide](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/KeyValueCoding/Articles/BasicPrinciples.html#//apple_ref/doc/uid/20002170-183455) is very clear about this. Dots are used to invoke accessor methods. So there is no way to solve your problem. – VenoMKO Feb 07 '14 at 16:44

1 Answers1

0

Since it is not possible to use dots in the keys in your NSDictionary with KVO, you could instead hash the string containing the dot syntax, and use that for the key. This would provide a uniquely identifiable key, while preserving the dot syntax - albeit with some hash/de-hash overhead.

cleverbit
  • 5,514
  • 5
  • 28
  • 38
  • You can have _anything_ in your NSDictionary keys. Doesn't even have to be strings (and I have use dictionaries with different keys all the time). It is only key/value observation has problems with it. – gnasher729 May 20 '15 at 17:18