合并NSDictionaries - NSUnknownKeyException

时间:2013-01-15 05:34:24

标签: ios objective-c nsdictionary

我正在尝试合并两个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'

latitudegpsAttributes

中的关键字

1 个答案:

答案 0 :(得分:10)

这里的问题是你不是在处理普通词典,而是使用NSKnownKeysDictionary,这是Apple在Cocoa的各个部分使用的无证类型。

如果您从SDK转储ObjC类信息,或者,如果这听起来太可怕了,请阅读someone else's version - 您可以看到这实际上是NSMutableDictionary的子类,而不仅仅是{{1}因此它已经是可变的,所以你的NSDictionary不是必需的。

更重要的是,如果您阅读了如何定义NSCopyingNSMutableCopying协议,那么就没有任何东西需要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并将其浅层复制到您控制的类型的字典中。