objective-c - NSMutableDictionary KVO

标签 objective-c key-value-observing

我正在尝试使用 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/

相关文章:

ios - 为 ios 开发应用程序我应该支持快速或慢速连接?

ios - 如何获取KVO#keyPath(WKWebView.url)的URL值?

cocoa - 如何绑定(bind) CAConstraint 的比例?

ios - 如何从 uitableViewCell 中删除 KVO 观察器?

iphone - CoreData 为所有对象和键注册全局观察者

objective-c - NSDictionary setValue :

objective-c - 如何检测 Mac 应用程序中的应用程序是否处于非事件状态

objective-c - 从 NSColor 创建 NSImage

objective-c - 从 CGColorCreateGenericRGB 中的 NSColorWell 获取颜色

objective-c - OSX 中的事务性文件操作