我正在尝试合并两个NSDictionaries:
NSDictionary *areaAttributes = [[area entity] attributesByName];
NSDictionary *gpsAttributes = [[gps entity] attributesByName];
NSMutableDictionary *combinedAttributes = [areaAttributes mutableCopy];
[combinedAttributes addEntriesFromDictionary:gpsAttributes];
但是出现以下错误:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: 'The key 'latitude' is not defined for this NSKnownKeysDictionary'
latitude
是gpsAttributes
中的键 最佳答案
这里的问题是您不是在处理普通字典,而是在使用NSKnownKeysDictionary
,这是Apple在Cocoa的各个部分中使用的未记录类型。
如果从SDK中转储ObjC类信息-或者,如果听起来太吓人,请阅读someone else's version-您会发现这实际上是NSMutableDictionary
的子类,而不仅仅是NSDictionary
,因此它已经可变,因此不需要mutableCopy
。
更重要的是,如果您阅读了 NSCopying
和 NSMutableCopying
协议(protocol)的定义方式,那么没有什么要求mutableCopy
返回与它的基类可兼容的东西了。只是它是可变的,并且与其基类具有不变的兼容性。真烦人。
答案是生成一个新的可变字典,并将 key 从两个NSKnownKeysDictionary
对象复制到该字典中:
NSDictionary *areaAttributes = [[area entity] attributesByName];
NSDictionary *gpsAttributes = [[gps entity] attributesByName];
NSMutableDictionary *combinedAttributes = [NSMutableDictionary dictionaryWithCapacity:20];
[combinedAttributes addEntriesFromDictionary:areaAttributes];
[combinedAttributes addEntriesFromDictionary:gpsAttributes];
(显然,如果您担心性能,则可以调整
20
,或者从每个字典中获取键的数量并传递总数。但是通常,这无关紧要。)您可能想知道苹果为什么要这么做。但是,如果您考虑一下,这是一件方便的事情。在某些库的内部,您有一个可以像C
struct
一样使用的对象,但在外部看起来像NSDictionary
。 (类似于Python中的namedtuple
的目的。)返回它们的方法都旨在返回NSDictionary
,而不是NSMutableDictionary
,因此没有人会知道它们的键集受到限制。当然,除非他们调用mutableCopy
。您可能还想知道如何提前知道这一点。好吧,你真的不能。记录对象的类型,编写异常处理程序并记录异常,或者让其崩溃并在崩溃转储中找到该异常。或者,您也可以采取防御措施,并假设任何词典都可以给您一个无用的
mutableCopy
,然后将其浅拷贝到您控制的类型的词典中。关于ios - 合并NSDictionaries-NSUnknownKeyException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14331715/