NSMutableDictionary со слабыми ссылками: предупреждение при использовании CFRetain в качестве обратного вызова - PullRequest
1 голос
/ 02 февраля 2011

Я пытаюсь создать изменяемый словарь, в котором есть слабые ссылки для объектов-значений (ключи ведут себя нормально).Вот как я пытаюсь это сделать:

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

К сожалению, я получаю предупреждение ( Инициализация от несовместимого типа указателя ) при объявлении keyCallbacks, и я его отслеживалвплоть до использования CFRetain и CFRelease.По некоторым причинам эти обратные вызовы не совпадают с необходимыми прототипами (CFDictionaryRetainCallback и CFDictionaryReleaseCallback)

В документации говорится, что пример CFDictionaryRetainCallback должен выглядеть примерно так:

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

Но существующий CFRetainобъявляется как

CFTypeRef CFRetain(CFTypeRef cf);

В нем отсутствует параметр allocator, и поэтому я думаю, что компилятор выдает предупреждение: это не идеальное совпадение в сигнатуре функции.

Кто-нибудь пыталсясделать что-то подобное?

Ответы [ 4 ]

5 голосов
/ 02 февраля 2011

Не делай этого. Используйте NSMapTable.

1 голос
/ 02 февраля 2011

, если вы просто хотите поведение по умолчанию CFRetain / CFRelease, это должно сработать:

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

оттуда должно быть легко реализовать удержание обратного вызова.

0 голосов
/ 24 августа 2013

Если вы не возражаете немного поиграть со средой выполнения, это - это то, над чем я работаю для моего проекта (работает ATM, но немного неаккуратно).Он динамически создает новый подкласс любого добавляемого объекта и устанавливает класс этого объекта в подкласс.Подкласс содержит массив объектов, о которых следует уведомлять всякий раз, когда объект освобождается.Словарь добавляет себя в этот массив, чтобы он мог удалить объект, если он когда-либо освобожден.

0 голосов
/ 02 февраля 2011

Мне удалось заставить его работать, используя константу kCFTypeDictionaryKeyCallBacks вместо ручного объявления ключевых обратных вызовов. Код теперь выглядит так:

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

Однако мне все еще любопытно, почему мой первоначальный код не работает

...