cocoa 的 NSDictionary : why are keys copied?

标签 cocoa data-structures nsdictionary nsmutabledictionary

所有在 NS(Mutable)Dictionaries 中用作键的对象都必须支持 NSCopying 协议(protocol),并且这些对象在字典中使用时会被复制。

我经常想使用较重的对象作为键,只是将一个对象映射到另一个对象。当我这样做时,我真正的意思是有效:

[dictionary setObject:someObject forKey:[NSValue valueWithPointer:keyObject]];

(“当我回来并再次向您提供相同的关键对象实例时,请为我提供相同的值。”)

...这正是我有时为了解决这个设计而最终所做的事情。 (是的,我知道桌面 Cocoa 中的 NSMapTable;但例如 iPhone 不支持此。)

但是我真正不明白的是为什么复制 key 首先是必要的或可取的。它为实现或调用者买了什么?

最佳答案

该副本确保用作键的值在用作键时不会“暗中”更改。考虑可变字符串的示例:

NSMutableString* key = ... 
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];

[dict setObject: ... forKey: key];

假设字典没有复制 key ,而只是保留它。如果现在,在稍后的某个时刻,原始字符串被修改,那么即使您使用完全相同的键对象(即一个 ),您也很可能不会再次在字典中找到存储的值。 key 指向上面示例中的位置)。

为了保护自己免受此类错误的影响,字典会复制所有键。

顺便说一句,请注意,将 -copyWithZone: 定义为 return [self keep] 非常简单。如果你的对象是不可变的,那么这是允许的,并且是好的代码,并且 NSCopying 合约是专门设计的,使得返回的对象必须(有点,有点)不可变:

Implement NSCopying by retaining the original instead of creating a new copy when the class and its contents are immutable.

(来自 NSCopying Reference )

The copy returned is immutable if the consideration “immutable vs. mutable” applies to the receiving object; otherwise the exact nature of the copy is determined by the class.

(来自 -copyWithZone: Reference )

即使您的对象不是不可变的,如果您只使用基于身份的相等/哈希实现,即不受对象内部状态以任何方式影响的实现,您也可能会摆脱该实现。

关于 cocoa 的 NSDictionary : why are keys copied?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2394083/

相关文章:

c++ - C/C++ 结构枚举

ios - 一次性将所有 Realm 对象转换为字典

objective-c - 如何为带有嵌入式 NSProgressIndicator 的菜单项创建 NSMenuItem View ?

kotlin - 根据属性对象将列表的属性合并到另一个列表

java - 如何使用不同的比较器创建通用结构的两个实例?

ios - [iOS][objC] 无法将 NSDictionary 中的值转换为 NSString

ios - 如何将 NSMutableDictionary 值传递给 Storyboard 中的多个 Controller ?

iphone - 按一个键然后按另一个键对数组进行排序?

swift - 如何在 NSStatusBar 中绘制自定义 View ?

ios - 强制或 "encouraging"iCloud 将更改上传到文件