хранение структуры в качестве значения с использованием CFDictionarySetValue ()

Я новичок в использовании основных фондов. Я хочу использовать словарь для хранения некоторой пары ключ-значение. Значение должно быть указателем на структуру. Этот указатель указывает на динамически распределяемый буфер.

CFMutableDictionaryRef init_hash_table() {

return CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}

Это используется для создания словаря, а возвращаемое значение сохраняется как глобальная переменная.

CFNumberRef
create_hash_key(int sd) {
return CFNumberCreate(NULL, kCFNumberIntType, &sd);
}int
add_hash_entry(CFMutableDictionaryRef dict, int sd, void *pkt) {

CFNumberRef key = create_hash_key(sd);

CFDictionarySetValue(dict, key, pkt);
return 0;
}

Когда я выполняю этот код, я получаю segfault. Я вижу, что pkt имеет действительный адрес и ключ, кажется, создан. Кто-нибудь знает, как назначить указатель на значение part?

Программа получила сигнал EXC_BAD_ACCESS, Не удалось получить доступ к памяти.
Причина: KERN_INVALID_ADDRESS по адресу: 0x0000000000000011
0x00007fff8c9f339f в objc_msgSend_fixup ()

Есть идеи?

2

Решение

Проблема заключается в kCFTypeDictionaryValueCallBacks аргумент. Из документации:

kCFTypeDictionaryValueCallBacks
предопределенный CFDictionaryValueCallBacks структура, содержащая набор
обратные вызовы, подходящие для использования, когда значения в CFDictionary являются
все CFTypeобъекты

Так что в вашем случае, CFRetain() вызывается по указателю, когда значение добавляется к
толковый словарь. Это вызывает сбой, потому что указатель не указывает на CoreFoundation
объект.

Вы можете создать словарь с

CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL);

вместо этого, чтобы не было никакого «подсчета ссылок» для значения.

Кроме того, вы можете заключить указатель в CFDataRef и положить это в
толковый словарь.

В обоих случаях вы несете ответственность за то, чтобы указатель действовал
когда значение извлекается из словаря позже.


Вот просто Пример того, как вы можете реализовать пересчет для ваших пользовательских объектов:

typedef struct {
int refcount;
int val;
} mystruct;

const void *myretain(CFAllocatorRef allocator, const void *value)
{
mystruct *p = (mystruct *)value;
p->refcount++;
return p;
}

void myrelease(CFAllocatorRef allocator, const void *value)
{
mystruct *p = (mystruct *)value;
if (p->refcount == 1)
free(p);
else
p->refcount--;
}

int main(int argc, const char * argv[])
{
mystruct *p = malloc(sizeof(*p));
p->refcount = 1;
p->val = 13;

CFDictionaryValueCallBacks vcb = { 0 , myretain, myrelease, NULL, NULL };
CFMutableDictionaryRef dict =  CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &vcb);

int sd = 13;
CFNumberRef key = CFNumberCreate(NULL, kCFNumberIntType, &sd);

CFDictionarySetValue(dict, key, p);
// refcount == 2
myrelease(NULL, p);
// refcount == 1

mystruct *q = CFDictionaryGetValue(dict, key);
// refcount is still 1, "GetValue" does not increment the refcount

CFRelease(dict);
// object is deallocated

return 0;
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]