ecb*_*tln 2 objective-c core-foundation nsmutabledictionary ios
我正在试图弄清楚如何创建一个保留而不是复制其键的NSMutableDictionary.我已经实现了 - (NSUInteger)哈希和 - (id)isEqual:对于我想要的密钥,我只是弄清楚要在回调中指定哪些选项.
CFDictionaryKeyCallBacks keyCallbacks = { 0, NULL, NULL, CFCopyDescription, CFEqual, NULL };
self.commonParents = (NSMutableDictionary*)CFBridgingRelease(CFDictionaryCreateMutable(nil, 0, &keyCallbacks, &kCFTypeDictionaryValueCallBacks));
Run Code Online (Sandbox Code Playgroud)
上面的代码在ARC中正确使用对键的弱引用,但是如果我想要强引用呢?关键回调应该是什么样的?
TL;博士:
CFDictionaryRef使用提供的默认回调函数创建一个.它会做你想要的.只是不要称之为NSDictionary.
是的,您可以创建一个CFDictionaryRef保留其键并且不复制它们的键.事实上,这是a 的默认行为CFDictionaryRef.
文档CFDictionaryCreateMutable()说:
如果字典仅包含CFType对象,则将指针
kCFTypeDictionaryKeyCallBacks作为此参数传递以使用默认回调函数.
(所以如果你只是将普通的Objective-C对象放入数组而不是像void *指针或其他任何东西这样的随机事物,这就是你想要的)
文档kCFTypeDictionaryKeyCallBacks说:
预定义
CFDictionaryKeyCallBacks结构,包含一组适用于CFDictionary的键都是CFType派生对象时使用的回调.保留回调是CFRetain,释放回调是CFRelease,复制回调是CFCopyDescription,相等的回调是CFEqual.因此,如果在创建字典时使用指向此常量的指针,则在添加到集合时会自动保留键,并在从集合中删除时释放.
请注意,retain回调是,CFRetain()而不是CFCopyObject(实际上并不存在).
事实上,核心基础没有一个规范的方法,以"复制任何对象",这就是为什么像功能CFStringCreateCopy,CFArrayCreateCopy,CGPathCreateCopy存在,等等.
那么,你可以做的就是像这样创建你的字典:
CFDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
Run Code Online (Sandbox Code Playgroud)
而且你现在有一个字典可以保留其密钥并且不会复制它们.
我打算用大字写下这一点,这样你就可以说出我要说的话:
NSDictionary.是的,NSDictionary并且CFDictionaryRef是免费的桥接.但是,铸造这CFDictionaryRef一个NSDictionary将是桥接的滥用,因为这条线在NSDictionary文档:
......密钥可以是任何对象(前提是它符合
NSCopying协议 - 见下文)
同样,文档-[NSMutableDictionary setObject:forKey:]明确说明:
密钥被复制(使用
copyWithZone:;密钥必须符合NSCopying协议).
字典中的键不必符合<NSCopying>也不使用复制-copyWithZone:,这意味着您的字典不是NSDictionary(或NSMutableDictionary).每当您NSDictionary在代码中看到使用时,您应该提供一个键值映射,其中键被复制(不保留).这是API合同.要做任何其他事情可能会导致未定义的行为.
(某些对象覆盖的事实-copy来return [self retain]是一个实现细节,而不是与这一讨论相关的"什么是NSDictionary".)
| 归档时间: |
|
| 查看次数: |
962 次 |
| 最近记录: |