观察NSMutableDictionary更改

Sti*_*set 19 objective-c nsmutabledictionary

是否可以观察(订阅)对NSMutableDictionary中不同键下存储的值的更改?在我的情况下,启动订阅时密钥已经存在,但值会更改,我希望在这种情况下得到通知.我想要通知中更改值的键.

我假设如果我的字典键都是NSString实例,我可以单独订阅每个键路径.但是,如果我的键是非字符串怎么办?那个案子我运气不好吗?

Qui*_*lor 6

这是一个有趣的想法.我在NSDictionary或NSDictionaryController中找不到任何看起来很有前途的东西.我的第一直觉是使用NSMutableDictionary周围的组合,并拦截对setObject:forKey :(和-removeObjectForKey :)的调用,以通知订阅者更改.

在子类化NSMutableDictionary上有一个Cocoa With Love帖子,如果你选择去那条路线,它可能会很有用.我也创建了自己的NSMutableDictionary子类,欢迎您使用开源代码.

您可以设计一个可以指定应监视的特定键的观察器协议.不应该是太多的代码,但比我现在有时间抛弃.


Sti*_*set 6

我已经使用NSMutableDictionary周围的组合成功实现了这一点.我很惊讶它花了很少的代码.我实施的课程是Board,用于表示棋盘游戏中的模型.任何人都可以通过调用addObserver:方法订阅板状态的更改,实现如下:

- (void)addObserver:(id)observer {
    for (id key in grid)
        [self addObserver:observer
               forKeyPath:[key description]
                  options:0
                  context:key];
}
Run Code Online (Sandbox Code Playgroud)

由于您只能使用KVO模型订阅密钥,因此我欺骗并订阅了密钥的描述,但将密钥本身作为上下文传递.在观察我的Board实例的对象中,我实现了-observeValueForKeyPath:ofObject:change:context:忽略keyPath字符串并只使用传入的上下文.

我使用此方法创建的人工属性不是KVO兼容的,因此我传入0options属性,因此KVO机器不会尝试获取这些键的旧值/新值.这会导致我的代码爆炸.

任何改变董事会的东西(在我的简单类中只有一种方法可以做到这一点)会引发必要的通知以使KVO机器跳跃行动:

- (void)setPiece:(id)piece atLocation:(Location*)loc {
    [self willChangeValueForKey:[loc description]];
    [grid setObject:piece forKey:loc];
    [self didChangeValueForKey:[loc description]];
}
Run Code Online (Sandbox Code Playgroud)

瞧!使用非字符串键订阅NSMutableDictionary!