Objective c NSMutableDictionary和新项目插入KVO

Objective c NSMutableDictionary和新项目插入KVO,objective-c,cocoa,nsmutabledictionary,key-value-observing,key-value-coding,Objective C,Cocoa,Nsmutabledictionary,Key Value Observing,Key Value Coding,让我先描述一下我的问题。我有一个类,它包含一个NSMutableDictionary ivar。有一个线程会将新的密钥对添加到此字典中-在编写应用程序时,我无法获得可用密钥的完整列表。必须在表视图中显示所有这些对的最新列表。 我准备了一个小型的概念验证应用程序,其中在xib文件中创建了一个字典控制器,其内容与字典ivar绑定。问题是表视图只显示字典内容的初始集。插入后,它不会刷新 在我的概念验证应用程序AppController.h中,如下所示: #import <Foundation/F

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

在我的概念验证应用程序AppController.h中,如下所示:

#import <Foundation/Foundation.h>

@interface AppController : NSObject

@property (strong) NSMutableDictionary *dictionary;

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

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

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

- (void)addDictionaryObject:(NSString *)object;
- (void)removeDictionaryObject:(NSString *)object;
问题在于
addDictionaryObject:
只有一个参数,dictionary需要类似于
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]);
}

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

您需要调用

 [_tableView reloadData];

这将告诉您的tableview从本质上刷新它所知道的一切

 [_tableView reloadData];
这将告诉您的tableview从本质上刷新它所知道的一切。

从文档中,许多属性只支持
NSMutableArray
NSMutableSet
。因为KVC已经可以使用键,所以支持
NSMutableDictionary
是多余的,因为
setValue:forKey:
已经有效地支持了它

如果您真的希望在一次调用中实现这一点,可以重写
setValue:forKeyPath:

从文档中,只有
NSMutableArray
NSMutableSet
支持多个属性。因为KVC已经可以使用键,所以支持
NSMutableDictionary
是多余的,因为
setValue:forKey:
已经有效地支持了它


如果您真的想在一次调用中实现这一点,可以重写
setValue:forKeyPath:

我知道这是可能的,但在我的实际应用程序中,它会打破MVC模式-我不想在我的DataManager类中有一个出口。某种方法是使用block调用
realoadData:
方法,但我觉得KVO-it设计用于处理像我这样的问题。@Krokodylowy:AppController必须是一个控制器类(否则您已经破坏了模式)。在
-addRandomPair:
@JeremyP中发送
-reloadData
不会破坏MVC。问题中发布的源代码只是一个概念验证应用程序。真正的应用程序有一个模型,其中是DataManager,模型由ModelController(facade设计模式)处理,AppController有ModelController的ivar,还有几个窗口(每个窗口都有一个自定义的NSWindowController类)所以我真的希望使用KVO而不是调用
reloadData:
。我知道这是可能的,但在我的实际应用程序中,它会打破MVC模式-我不希望在我的DataManager类中有一个出口。某种方法是使用block调用
realoadData:
方法,但我觉得KVO-it设计用于处理像我这样的问题。@Krokodylowy:AppController必须是一个控制器类(否则您已经破坏了模式)。在
-addRandomPair:
@JeremyP中发送
-reloadData
不会破坏MVC。问题中发布的源代码只是一个概念验证应用程序。真正的应用程序有一个模型,其中是DataManager,模型由ModelController(facade设计模式)处理,AppController有ModelController的ivar,还有几个窗口(每个窗口都有一个自定义的NSWindowController类)所以我真的希望使用KVO而不是调用
reloadData:
。很难说它是否是多余的。在我的情况下,我不会说它是多余的,这里的字典只是一个数据结构。我可以使用NSMutableArray,并将键和值存储在新数据类中。从KVO的角度来看,它不会是多余的,但对我来说,它会降低性能,因为每次更新值都需要迭代整个集合……我认为您考虑得太多了。您有一个保存字典的对象,您试图在一次调用中既访问它,又为一个键指定一个值。只需将其拆分为两个KVC调用就会容易得多:一个用于获取字典(就像任何属性一样),然后在字典上执行
setValue:forKey:
。否则,可能会覆盖控制器的
setValue:forKeyPath:
。今天我仔细学习了键值编码编程指南,您的回答是正确的,只有NSMutableArray和NSMutableSet支持许多属性。现在,我将设计一个包含字典的类,但所有的访问器方法都要使用KVO进行编译,其行为类似于NSMutableArray。谢谢。很难说这是否是多余的。在我的情况下,我不会说它是多余的,这里的字典只是一个数据结构。我可以使用NSMutableArray,并将键和值存储在新数据类中。从KVO的角度来看,它不会是多余的,但对我来说,它会降低性能,因为每次更新值都需要迭代整个集合……我认为您考虑得太多了。你有一个对象
 [_tableView reloadData];