我正在尝试使用至少两种方法为NSMutableDictionary类实现类别:一种用于NSDictionary 保留(不复制)其键,另一种用于NSDictionary 弱引用它的键(即对它们没有任何作用)。
在两种情况下都会保留值。
因此,由于CFDictionaryRef被认为是免费的NSDictionary桥接,我实际上做了以下事情:
+ (NSMutableDictionary *)dictionaryWithWeakReferencedKeysForCapacity: (NSUInteger)capacity
{
CFDictionaryKeyCallBacks keyCallbacks = { 0, NULL, NULL, CFCopyDescription, CFEqual, NULL };
CFDictionaryValueCallBacks valueCallbacks = { 0, ___f_KBWS_DICTIONARY_RETAIN_CALLBACK, ___f_KBWS_DICTIONARY_RELEASE_CALLBACK, CFCopyDescription, CFEqual };
return [(id)CFDictionaryCreateMutable(NULL, capacity, &keyCallbacks, &valueCallbacks) autorelease];
}
第二种方法(对于保留的键)看起来很相似,这里没有介绍。 代码中的可怕函数是:
static const void *___f_KBWS_DICTIONARY_RETAIN_CALLBACK(CFAllocatorRef allocator, const void *value)
{
id object = (id)value;
return [object retain];
};
static void ___f_KBWS_DICTIONARY_RELEASE_CALLBACK(CFAllocatorRef allocator, const void *value)
{
id object = (id)value;
return [object release];
};
一旦我找不到用于保留和释放密钥的标准核心基础回调,我就必须自己写这些。
我计划将这些类别用于仅存储子类NSObjects的字典。 问题是:对于这种情况,这些有效的回调是什么? 除了那之外我的代码还有什么问题吗?
答案 0 :(得分:2)
我认为这些回调本身没有任何问题。也就是说,你应该小心“将”NSMutableDictionaries“分发”给那些行为不像普通NSMutableDictionaries的“公共”。
详细说明,给某人一个NSMutableDictionary指针隐含地说明该对象的行为方式。已将其设置为CFMutableDictionary,具有非标准回调,并通过Toll-Free Bridging编译的魔力进行投射,但正在设置消费者失败。
更一般地说,我会说你可以不受惩罚地做到这一点,只要你保持字典私有任何类拥有它。你的代码片段暗示你可能会以NSMutableDictionary为幌子将其传递给“世界其他地方”,但事实并非如此。
如果您必须将这些实例移出,我建议您创建自己的自定义NSMutableDictionary子类,如“MyWeakRefKeyMutableDictionary”并显式返回该类型。然后,至少如果有人将其视为NSMutableDictionary,他们不能说他们没有被警告。
答案 1 :(得分:2)
一旦我找不到用于保留和释放密钥的标准核心基础回调,我就必须自己写这些。
我认为你是在CFRetain
和CFRelease
之后。但是,如果您只想更改关键回调,则可以使用标准kCFTypeDictionaryValueCallBacks
。
+ (NSMutableDictionary *)dictionaryWithWeakReferencedKeysForCapacity: (NSUInteger)capacity
{
CFDictionaryKeyCallBacks keyCallbacks = { 0, NULL, NULL, CFCopyDescription, CFEqual, NULL };
return [(id)CFDictionaryCreateMutable(NULL, capacity, &keyCallbacks, &kCFTypeDictionaryValueCallBacks) autorelease];
}