我正在尝试合并两个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
答案 0 :(得分:10)
这里的问题是你不是在处理普通词典,而是使用NSKnownKeysDictionary
,这是Apple在Cocoa的各个部分使用的无证类型。
如果您从SDK转储ObjC类信息,或者,如果这听起来太可怕了,请阅读someone else's version - 您可以看到这实际上是NSMutableDictionary
的子类,而不仅仅是{{1}因此它已经是可变的,所以你的NSDictionary
不是必需的。
更重要的是,如果您阅读了如何定义NSCopying
和NSMutableCopying
协议,那么就没有任何东西需要mutableCopy
来返回与其基类可互换的东西;只是它是可变的,并且与其基类不可分割地兼容。这很烦人。
这里的答案是生成一个新的可变字典,并将两个 mutableCopy
个对象中的密钥复制到:
NSKnownKeysDictionary
(显然,如果你担心性能问题,你要么想要调整NSDictionary *areaAttributes = [[area entity] attributesByName];
NSDictionary *gpsAttributes = [[gps entity] attributesByName];
NSMutableDictionary *combinedAttributes = [NSMutableDictionary dictionaryWithCapacity:20];
[combinedAttributes addEntriesFromDictionary:areaAttributes];
[combinedAttributes addEntriesFromDictionary:gpsAttributes];
,要么从每个字典中获取密钥的数量并传入总数。但通常,这并不重要。 )
您可能想知道为什么Apple会这样做。但如果你考虑一下,这是一个方便的事情。你有一个对象可以在某个库的内部像C 20
一样使用,但外部看起来就像struct
。 (与Python中的NSDictionary
类似的目的。)返回它们的方法都旨在返回namedtuple
,而不是NSDictionary
,所以没有人会知道它们有一个限制集钥匙当然,除非他们致电NSMutableDictionary
。
您可能也想知道如何提前了解这一点。好吧,你真的不能。您可以记录对象的类型,编写异常处理程序并记录异常,或者让它崩溃并在崩溃转储中找到异常。或者,或者,您可以采取防御措施,并假设任何字典都可以为您提供无用的mutableCopy
并将其浅层复制到您控制的类型的字典中。