NSMutableDictionary和新项目插入KVO

时间:2011-11-17 14:28:56

标签: objective-c cocoa nsmutabledictionary key-value-observing key-value-coding

让我先描述一下我的问题。我有一个包含NSMutableDictionary ivar的类。有一个线程会将新对添加到此字典中 - 在编写应用程序时,我无法获得可用密钥的完整列表。必须在表视图中显示所有这些对的最新列表。 我已经准备了小概念证明应用程序,其中在xib文件中创建了一个Dictionary Controller,其内容与字典ivar绑定。问题是表视图仅显示字典内容的初始设置。插入后它没有刷新。

在我的概念验证应用AppController.h中如下:

#import <Foundation/Foundation.h>

@interface AppController : NSObject

@property (strong) NSMutableDictionary *dictionary;

- (NSString *)randomString;
- (IBAction)addRandomPair:(id)sender;

@end

实施文件内容:

#import "AppController.h"

@implementation AppController

@synthesize dictionary = _dictionary;

- (id)init {
    self = [super init];
    if (self) {
        _dictionary = [[NSMutableDictionary alloc] init];
        [_dictionary setValue:@"Aa" forKey:@"A"];
        [_dictionary setValue:@"Bb" forKey:@"B"];
    }
    return self;
}

- (NSString *)randomString
{
    NSMutableString *aString = [[NSMutableString alloc] init];
    for (int i = 0; i < 3; i++) {
        NSUInteger r = random() % ('z' - 'a');
        [aString appendString:[NSString stringWithFormat:@"%c", ('a' +r)]];
    }
    return aString;
}

- (IBAction)addRandomPair:(id)sender
{
    [self.dictionary setValue:[self randomString] forKey:[self randomString]];
    NSLog([self.dictionary description]);
}

@end

字典控制器内容绑定到App Controller,模型键路径设置为“self.dictionary”,表视图中的列内容绑定到字典控制器,模型键路径相应地设置为键和值。在此概念验证应用程序按钮单击中添加一个新对(addRandomPair:action)。

我遇到了类似NSMutableArray和Array Controller的问题,但是我能够通过向包含数组ivar的类(在此类中命名数据)中添加以下一对方法来解决问题:

- (void)insertObject:(NSString *)object inDataAtIndex:(NSUInteger)index;
- (void)removeObjectFromDataAtIndex:(NSUInteger)index;

是否可以在持有字典(AppController)的类中添加一些其他方法以获得有关新插入的通知?或者对我的问题有更好的解决方案吗?

更新

我发现实现以下一组访问器会使Dictionary Controller收到有关新项目的通知:

- (void)addDictionaryObject:(NSString *)object;
- (void)removeDictionaryObject:(NSString *)object;

问题是addDictionaryObject:只有一个参数,字典需要addDictionaryObject:forKey:之类的东西。有什么想法吗?

更新2

除了使用手动更改通知之外,我没有看到任何其他解决方案 - 在这种情况下,addRandomPair:方法如下所示:

- (IBAction)addRandomPair:(id)sender
{
    [self willChangeValueForKey:@"dictionary"];
    [self.dictionary setValue:[self randomString] forKey:[self randomString]];
    [self didChangeValueForKey:@"dictionary"];
    NSLog([self.dictionary description]);
}

它有效,但我仍然有点不确定,因为字典本身不会改变,但它的内容。 在这里使用手动更改通知是否正确?

2 个答案:

答案 0 :(得分:4)

Key-Value Coding methods文档中,To-Many属性仅支持NSMutableArrayNSMutableSet。既然,KVC已经使用密钥,那么支持NSMutableDictionary将是多余的,因为setValue:forKey:已经有效了。

如果您真的希望在一次通话中使用,请覆盖setValue:forKeyPath:

答案 1 :(得分:0)

您需要调用类似

的内容
 [_tableView reloadData];

这将告诉你的tableview基本上刷新它所知道的一切。