这里的问题是你不是在处理普通的字典,而是在处理NSKnownKeysDictionary
,这是 Apple 在 Cocoa 的各个部分中使用的一种未记录的类型。
如果您从 SDK 中转储 ObjC 类信息——或者,如果这听起来太吓人,请阅读其他人的版本——您会发现这实际上是 的子类NSMutableDictionary
,而不仅仅是NSDictionary
,所以它已经是可变的,所以你mutableCopy
的不是必需的。
更重要的是,如果你阅读了NSCopying
和NSMutableCopying
协议是如何定义的,那么就没有什么需要mutableCopy
返回与它的基类可变兼容的东西了。只是它是可变的,并且与它的基类不可变地兼容。这很烦人。
这里的答案是生成一个新的可变字典,并将两个 对象的键复制NSKnownKeysDictionary
到其中:
NSDictionary *areaAttributes = [[area entity] attributesByName];
NSDictionary *gpsAttributes = [[gps entity] attributesByName];
NSMutableDictionary *combinedAttributes = [NSMutableDictionary dictionaryWithCapacity:20];
[combinedAttributes addEntriesFromDictionary:areaAttributes];
[combinedAttributes addEntriesFromDictionary:gpsAttributes];
(显然,如果您担心性能,您要么想要调整它20
,要么从每个字典中获取键的数量并传递总数。但通常,这并不重要。)
您可能想知道为什么 Apple 会这样做。但如果你仔细想想,这是一件很方便的事情。你有一个对象,可以struct
在某个库的内部像 C 一样使用,但在外部看起来就像NSDictionary
. (类似的目的,例如,namedtuple
在 Python 中。)返回它们的方法都被设计为 return NSDictionary
, not NSMutableDictionary
,所以没有人会知道他们有一组受限的键。当然,如果他们调用mutableCopy
.
您可能还想知道如何提前知道这一点。好吧,你真的不能。要么记录对象的类型,要么编写异常处理程序并记录异常,要么让它崩溃并在故障转储中找到异常。或者,或者,您可以采取防御措施,并假设任何字典都可以给您一个无用mutableCopy
且浅显的复制到您控制的类型的字典中。