首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSMutableDictionary KVO

NSMutableDictionary KVO
EN

Stack Overflow用户
提问于 2012-03-08 10:04:58
回答 5查看 7.5K关注 0票数 5

我正在尝试使用KVO观察字典中的变化。

示例:

代码语言:javascript
复制
dictionary = [NSMutableDictionary new];
[dictionary setObject:@"test1" forKey:@"key1"];
[dictionary setObject:@"test2" forKey:@"key2"];    
[dictionary setObject:@"test3" forKey:@"key1"];

我希望无论何时向字典中添加一个值,都能吸引一个观察者。移除或替换(即在上述情况下,只要调用任何setObject方法)

所以总而言之:我想要一个函数有

代码语言:javascript
复制
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

当我向字典中添加任何新条目,或移除任何条目,或替换任何条目时调用。

NOT:我不想指定要观察哪些键。(例如,仅当添加@"key1“时才观察),因为此解决方案不能扩展。

EN

回答 5

Stack Overflow用户

发布于 2012-03-08 19:30:55

对NSMutableDictionary进行子类化有点麻烦,因为NSDictionary和它的朋友都是类簇。这当然是可行的,如果您必须将对象本身传递给另一组类,那么您可能希望这样做。否则,创建一个具有相同基本API并在内部使用NSMutableDictionary对象进行存储的复合类可能会更容易。有一篇很好的文章,写成了CocoaWithLove.com,Ordered Dictionary Subclassing,就是这样做的。

然而,这并不能完全解决您的问题。我建议您从上面这样的子类或装饰器类开始,然后显式地添加对-(NSArray*)allKeys的支持,这是NSDictionary本身中的一个标准访问器。然后,您可以添加支持来传递allKeys的更改消息,这将使其可见。

这可以通过在-setObject:forKey:-removeObjectForKey:方法周围添加以下代码来完成。

代码语言:javascript
复制
- (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在set或remove上通知,如下所示:

代码语言:javascript
复制
- (void)setObject:(id)anObject forKey:(id)aKey
{
    [self willChangeValueForKey: @"allKeys"];   
    [dictionary setObject:anObject forKey:aKey];
    [self didChangeValueForKey: @"allKeys"];
}

然后,在您的代码中,您为该对象上的键@"allKeys“添加了一个观察者,无论何时项发生更改,您都会收到通知。

票数 8
EN

Stack Overflow用户

发布于 2016-11-03 06:23:22

我解决了一个类似的问题,向可变字典"translator“添加了一个观察者,如下所示:

代码语言:javascript
复制
[self addObserver:self forKeyPath:@"translator.@count" options:0 context:NULL];

我的应用程序以经典的方式管理数据,使用表视图、控制器和字典作为KVO属性的“翻译器”。字典绑定到我的XIB中的NSDictionaryController,表视图内容绑定到控制器。

以下是表视图的连接:

现在,在以下任何一种情况下,我都能捕捉到变化:

  • 添加键值对
  • 删除键值对
  • 更改密钥
  • 更改值代码<

>F211>

备注:不幸的是,这种方法不适用于NSMutableArrays。无法识别更改

票数 1
EN

Stack Overflow用户

发布于 2012-03-08 14:05:10

难道不能子类化NSMutableDictionary并覆盖各种setter方法吗?例如,通过调用Super...重写setObject:forKey,然后立即调用addObserver...

您还可以为NSMutableDictionary编写一个包装器,强制自己使用自定义设置器来操作底层的NSMutableDictionary。

也许我需要更多关于您的限制或可伸缩性意图的上下文。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9611965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档