Ben*_*tto 21 cocoa nsdictionary nsmutabledictionary data-structures
在NS(Mutable)词典中用作键的所有对象必须支持NSCopying协议,并且这些对象在字典中使用时会被复制.
我经常想要使用较重的物体作为键,只需将一个物体映射到另一个物体.当我这样做时,我真正的意思是:
[dictionary setObject:someObject forKey:[NSValue valueWithPointer:keyObject]];
Run Code Online (Sandbox Code Playgroud)
("当我回来再次交给你这个相同的关键对象实例时,给我相同的值.")
...这正是我最终做的有时候绕过这个设计.(是的,我知道桌面Cocoa中的NSMapTable;但是iPhone不支持这个.)
但我真正得到的是为什么首先复制密钥是必要的或可取的.它是如何购买实现或调用者的?
Dir*_*irk 26
该副本确保用作键的值在用作键时不会"改变".考虑一个可变字符串的示例:
NSMutableString* key = ...
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
[dict setObject: ... forKey: key];
Run Code Online (Sandbox Code Playgroud)
我们假设字典没有复制密钥,而只是retain编辑它.如果现在,在稍后的某个时刻,原始字符串被修改,那么即使您使用相同的密钥对象(即,key指向的那个),您很可能不会再次在字典中找到存储的值.上面的例子).
为了保护自己免受这样的错误,字典复制所有键.
顺便提一下,请注意,将其定义-copyWithZone:为仅仅是这样做很简单return [self retain].如果您的对象是不可变的,那么这是允许的和良好的代码,并且NSCopying合同是专门设计的,使得返回的对象必须是(sorta,kinda)不可变的:
通过保留原始而不是在类及其内容不可变时创建新副本来实现NSCopying.
(来自NSCopying参考)
和
如果考虑"immutable vs. mutable"适用于接收对象,则返回的副本是不可变的; 否则,副本的确切性质由班级决定.
(来自-copyWithZone:参考)
即使您的对象不是不可变的,如果您只使用基于身份的相等/散列实现,即实现不受对象内部状态影响的实现,您可能会逃避该实现.
从iOS 6开始,如果要使用指针作为键,则可以使用该NSMapTable对象,请参见http://nshipster.com/nshashtable-and-nsmaptable/
您可以指定键和/或值是紧握还是弱握:
NSMapTable *mapTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
valueOptions:NSMapTableWeakMemory];
Run Code Online (Sandbox Code Playgroud)
有时可能合适的另一种选择是使用NSCache,它可以牢固地保持键,并且实际上是线程安全的。
| 归档时间: |
|
| 查看次数: |
5177 次 |
| 最近记录: |