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