我正在尝试使用 KVO 观察字典中的变化。
例子:
dictionary = [NSMutableDictionary new];
[dictionary setObject:@"test1" forKey:@"key1"];
[dictionary setObject:@"test2" forKey:@"key2"];
[dictionary setObject:@"test3" forKey:@"key1"];
每当向字典中添加值时,我都希望能够 Hook 观察者。删除或替换(即在上述情况下,无论何时调用任何 setObject 方法)
总而言之: 我想要一个函数有
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
当我向字典添加任何新条目、删除任何条目或替换任何条目时调用。
NOT:我不想指定我正在观察的键。 (例如,仅在添加 @"key1"时观察)因为此解决方案无法扩展。
最佳答案
子类化 NSMutableDictionary 有点烦人,因为 NSDictionary 和它的 friend 是类簇。这当然是可行的,如果您必须将对象本身传递给另一组类,那么您可能想要这样做。否则,创建一个具有相同基本 API 并在内部使用 NSMutableDictionary 对象进行存储的复合类可能会更容易。 CocoaWithLove.com 上有一篇很好的文章,Ordered Dictionary Subclassing , 这就是这样做的。
但是,这并不能完全解决您的问题。我建议您从一个子类或装饰器类开始,例如上面的类,然后显式添加对 -(NSArray*)allKeys
的支持,它是 NSDictionary< 中的标准访问器
本身。然后,您可以添加支持以传递 allKeys 的更改消息,这将使其可观察。
这可以通过在 -setObject:forKey:
和 -removeObjectForKey:
方法周围添加以下代码来完成。
- (void)setObject:(id)anObject forKey:(id)aKey
{
BOOL addKey=NO;
if (![dictionary objectForKey: aKey]) {
addKey=YES;
[self willChangeValueForKey: @"allKeys"];
}
[dictionary setObject:anObject forKey:aKey];
if (addKey)
[self didChangeValueForKey: @"allKeys"];
}
- (void)removeObjectForKey:(id)aKey
{
[self willChangeValueForKey: @"allKeys"];
[dictionary removeObjectForKey:aKey];
[self didChangeValueForKey: @"allKeys"];
}
这里所做的是,当字典的键更改以标记数组中的更改时,我们向类添加显式 KVO 通知。
这将负责添加和删除。如果您希望在相同的基础上通知更改,您可以删除 if 语句,只让 allKeys 在设置或删除时通知,如下所示:
- (void)setObject:(id)anObject forKey:(id)aKey
{
[self willChangeValueForKey: @"allKeys"];
[dictionary setObject:anObject forKey:aKey];
[self didChangeValueForKey: @"allKeys"];
}
然后,在您的代码中,您为该对象上的键 @"allKeys"放置了一个观察者,并且您将在项目发生更改时收到通知。
关于objective-c - NSMutableDictionary KVO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9611965/