创建自定义 CFDictionary 回调

发布于 2024-10-15 02:16:16 字数 1258 浏览 7 评论 0原文

我正在尝试使用至少两种方法来实现 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];
};

一旦我没有找到用于保留和释放键的标准核心基础回调,我就必须自己编写这些函数。

我计划将这些类别用于仅存储 NSObject 子类的字典。 问题是:对于这种情况,这些回调是否有效? 除此之外我的代码还有什么问题吗?

I am trying to implement categories for NSMutableDictionary class with at least two methods: one for NSDictionary that retains (not copies) its keys, and one for NSDictionary that weak references its keys (i.e. does nothing to them).

Values are simply retained in both cases.

Thus, as CFDictionaryRef is said to be toll-free bridged with NSDictionary, I actually do the following:

+ (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]; 
}

The second method (for retained keys) looks alike and is not presented here.
Scary functions inside the code are:

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];
};

I had to write these myself as soon as I haven't found standard core foundation callbacks for retaining and releasing keys.

I plan to use these categories for dictionaries that will store subclasses NSObjects only.
The question is: are these valid callbacks for this case?
Is there something wrong in my code besides that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不忘初心 2024-10-22 02:16:16

我认为这些回调本身没有任何问题。也就是说,您应该小心地将 NSMutableDictionaries 分发给“公众”,因为它们的行为与正常的 NSMutableDictionaries 不同。

详细地说,给某人一个 NSMutableDictionary 指针就隐式地声明了该对象的行为方式。将其设置为具有非标准回调的 CFMutableDictionary,并通过免费桥接编译的魔力对其进行转换,但正在为消费者设置失败。

更一般地说,我想说,只要你将字典保留给拥有它的任何类,你就可以不受惩罚地做到这一点。您的代码片段暗示您可能会打着 NSMutableDictionary 的幌子将其分发给“世界其他地方”,但事实并非如此。

如果您必须分发这些实例,我建议您创建自己的自定义 NSMutableDictionary 子类,例如“MyWeakRefKeyMutableDictionary”并显式返回该类型。那么至少如果有人把它当作 NSMutableDictionary 对待,他们就不能说他们没有收到警告。

I don't see anything wrong with these callbacks, per se. That said, you should be careful about "handing out" NSMutableDictionaries to the "public" that don't behave like normal NSMutableDictionaries.

To elaborate, giving someone an NSMutableDictionary pointer is implicitly making statements about how that object behaves. Having set it up as a CFMutableDictionary, with non-standard callbacks, and casting it by the magic of Toll-Free Bridging compiles, but is setting the consumer up for failure.

More generally, I would say that you can do this with impunity as long as you keep the dictionary private to whatever class owns it. Your code snippet implies that you might be handing this out to "the rest of the world" under the guise of being an NSMutableDictionary, when that's not really the case.

If you've got to hand these instances out, I would recommend making your own custom NSMutableDictionary subclass like "MyWeakRefKeyMutableDictionary" and returning that type explicitly. Then at least if someone treats it like an NSMutableDictionary, they can't say they weren't warned.

白色秋天 2024-10-22 02:16:16

一旦我还没有找到用于保留和释放密钥的标准核心基础回调,我就必须自己编写这些内容。

我认为您正在寻找 CFRetainCFRelease。但如果您只想更改按键回调,则可以使用标准的 kCFTypeDictionaryValueCallBacks。

+ (NSMutableDictionary *)dictionaryWithWeakReferencedKeysForCapacity: (NSUInteger)capacity
{   
    CFDictionaryKeyCallBacks    keyCallbacks    = { 0, NULL, NULL, CFCopyDescription, CFEqual, NULL }; 

    return [(id)CFDictionaryCreateMutable(NULL, capacity, &keyCallbacks, &kCFTypeDictionaryValueCallBacks) autorelease]; 
}

I had to write these myself as soon as I haven't found standard core foundation callbacks for retaining and releasing keys.

I think you're after CFRetain and CFRelease. But if you only want to change the key callbacks you can use the standard kCFTypeDictionaryValueCallBacks.

+ (NSMutableDictionary *)dictionaryWithWeakReferencedKeysForCapacity: (NSUInteger)capacity
{   
    CFDictionaryKeyCallBacks    keyCallbacks    = { 0, NULL, NULL, CFCopyDescription, CFEqual, NULL }; 

    return [(id)CFDictionaryCreateMutable(NULL, capacity, &keyCallbacks, &kCFTypeDictionaryValueCallBacks) autorelease]; 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文