Ram*_*sel 5 objective-c nsdictionary ios
我正在尝试合并两个NSDictionaries:
NSDictionary *areaAttributes = [[area entity] attributesByName];
NSDictionary *gpsAttributes = [[gps entity] attributesByName];
NSMutableDictionary *combinedAttributes = [areaAttributes mutableCopy];
[combinedAttributes addEntriesFromDictionary:gpsAttributes];
Run Code Online (Sandbox Code Playgroud)
但是得到以下错误:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: 'The key 'latitude' is not defined for this NSKnownKeysDictionary'
Run Code Online (Sandbox Code Playgroud)
latitude 是关键 gpsAttributes
aba*_*ert 10
这里的问题是你不是在处理普通的词典,而是使用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];
Run Code Online (Sandbox Code Playgroud)
(显然,如果你担心性能,你要么想要调整它20,要么从每个字典中获取密钥的数量并传递总数.但通常,这并不重要.)
您可能想知道为什么Apple会这样做.但如果你考虑一下,这是一个方便的事情.你有一个对象可以struct在某个库的内部像C一样使用,但外部看起来就像一个NSDictionary.(类似的目的,例如,namedtuple在Python)返回它们的方法都旨在返回NSDictionary,没有NSMutableDictionary,所以没有人会知道他们有一个受限制的组键.当然,除非他们打电话mutableCopy.
您可能也想知道如何提前了解这一点.好吧,你真的不能.您可以记录对象的类型,编写异常处理程序并记录异常,或者让它崩溃并在崩溃转储中找到异常.或者,或者,您可以采取防御措施,并假设任何字典都可以为您提供无用mutableCopy且浅层复制到您控制的类型的字典中.
| 归档时间: |
|
| 查看次数: |
5728 次 |
| 最近记录: |