NSMutableDictionary KVO [英] NSMutableDictionary KVO

查看:109
本文介绍了NSMutableDictionary KVO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to observe changes in dictionary using KVO.

示例:

dictionary = [NSMutableDictionary new];
[dictionary setObject:@"test1" forKey:@"key1"];
[dictionary setObject:@"test2" forKey:@"key2"];    
[dictionary setObject:@"test3" forKey:@"key1"];

我很希望能够在将值添加到字典时吸引观察者.删除或替换(即在上述情况下,无论何时调用任何setObject方法)

I'd love to be able to hook an observer for whenever a value is added to the dictionary. removed, or replaced (ie in the above cases, whenever any of the setObject methods are called)

因此,结论是: 我想要一个函数

So in conclusion: I want a function to have

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

在我将任何新条目添加到字典中,删除任何条目或替换任何条目时调用.

called when I ADD a any new entry to a dictionary, or Remove any entry, or REPLACE any entry.

否:我不想指定要观察的键. (例如,仅在添加@"key1"时观察),因为此解决方案无法扩展.

NOT: I do NOT want to have to specify which keys I'm observing for. (eg observe only when @"key1" is added) as this solution doesn't scale.

推荐答案

NSMutableDictionary的子类化有点烦人,因为NSDictionary及其朋友是类集群.这当然是可行的,并且如果您必须将对象本身传递给另一组类,那么您可能想要做到这一点.否则,创建具有相同基本API并在内部使用NSMutableDictionary对象进行存储的复合类可能会更容易.有一个很好的文章,例如CocoaWithLove.com,有序字典子类化,这个.

Subclassing NSMutableDictionary is a bit annoying, due to the fact that NSDictionary and its friends are class clusters. It's certainly doable, and if you have to pass the object itself to another set of classes, then you may want to do exactly that. Otherwise, it might be easier to create a composite class which has the same basic API and uses NSMutableDictionary object internally for storage. There's a pretty good write-up as CocoaWithLove.com, Ordered Dictionary Subclassing, which goes into doing this.

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

However, that doesn't completely solve your problem. What I would suggest is that you begin with a subclass or decorator class such as the one above, then add support explicitly for -(NSArray*)allKeys, which is a standard accessor in NSDictionary itself. Then, you can add support to pass along change messages for allKeys, which will make it observable.

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

This can be done by adding the following code around the -setObject:forKey: and -removeObjectForKey: methods.

- (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通知.

What is being done here is that we're adding explicit KVO notification to the class when the dictionary's keys are changed to mark a change in the array.

这将负责添加和删除.如果希望在相同的基础上通知更改,则可以删除if语句,而只对allKeys进行设置或删除通知,就像这样:

This will take care of adds and removes. If you want changes to be notified on the same basis, you can remove the if statements, and just have allKeys notify on either set or remove, like this:

- (void)setObject:(id)anObject forKey:(id)aKey
{
    [self willChangeValueForKey: @"allKeys"];   
    [dictionary setObject:anObject forKey:aKey];
    [self didChangeValueForKey: @"allKeys"];
}

然后,在您的代码中,您为该对象上的键@"allKeys"放置了一个观察者,每当项目更改时,您都将收到通知.

Then, in your code, you put in a single observer for the key @"allKeys" on this object and you'll be receiving notifications whenever an item changes.

这篇关于NSMutableDictionary KVO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆