开发者

NSMutableDictionary with weak-references: warning when using CFRetain as a callback

开发者 https://www.devze.com 2023-02-07 19:38 出处:网络
I\'m trying to create a mutable dictionary that has weak-references for the value objects (the keys behave normally).

I'm trying to create a mutable dictionary that has weak-references for the value objects (the keys behave normally). This is how i'm trying to do it:

+ (id)mutableDictionaryUsingWeakReferencesWithCapacity:(NSUInteger)capacity
{
    CFDictionaryKeyCallBacks keyCallbacks = {0, CFRetain, CFRelease, CFCopyDescription, CFEqual, CFHash};
    CFDictionaryValueCallBacks valueCallbacks = {0, NULL, NULL, CFCopyDescription, CFEqual};    
    id<NSObject> obj = (id)(CFDictionaryCreateMutable(NULL, capacity, &keyCallbacks, &valueCallbacks));
    return [obj autorelease];
}

Unfortunately I get a warning (Initialization from incompatible pointer type)in when declaring the keyCallbacks, and i've tracked it down to using CFRetain and CFRelease. For some reason these callbacks do not match the required prototypes (CFDictionaryRetainCallback and CFDictionaryReleaseCallback)

In the documentation it says that an example CFDictionaryRetainCallback should look something like this:

const void *MyCallBack (
   CFAllocatorRef allocator,
   const void *value
);

But the existing CFRetain is declared as

CFTypeRef CFRetain(CFTypeRef cf);

It's missing the allocator parameter and that's why I think the compiler gives a warning: it's not a perfect match in the signature of the function.

Has anybody tried to do so开发者_高级运维mething like this?


Don’t Do That. Use NSMapTable.


if you just want the default CFRetain/CFRelease behaviour, this should work:

void MONDictionaryReleaseCallback(CFAllocatorRef allocator, const void* value) {
#pragma unused(allocator)
    assert(value);
    if (0 != value) {
        CFRelease(value);
    }
}

the retain callback should be easy to implement from there.


I managed to get it working using the kCFTypeDictionaryKeyCallBacks constant instead of manually declaring the key callbacks. The code now looks like this:

id<NSObject> obj = (id)(CFDictionaryCreateMutable(NULL, capacity, &kCFTypeDictionaryKeyCallBacks, &valueCallbacks));

However, i'm still curious why isn't my initial code working


If you don't mind playing with the runtime a bit, this is something I'm working on for a project of mine (it works ATM but it's a bit sloppy). It dynamically creates a new subclass of any object you add and set that object's class to the subclass. The subclass keeps an array of objects that should be notified whenever the object is deallocated. The dictionary adds itself to this array so that it can remove the object if it's ever deallocated.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号