2

我是使用核心基础的新手。我想使用字典来存储一些键值对。该值必须是指向结构的指针。该指针指向动态分配的缓冲区。

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

当我执行这段代码时,我得到了段错误。我看到 pkt 有一个有效的地址,并且似乎创建了密钥。有谁知道如何分配指向值部分的指针?

程序收到信号 EXC_BAD_ACCESS,无法访问内存。原因:KERN_INVALID_ADDRESS 地址:0x0000000000000011 0x00007fff8c9f339f in objc_msgSend_fixup()

有任何想法吗?

4

1 回答 1

3

问题是kCFTypeDictionaryValueCallBacks争论。从文档中:

kCFTypeDictionaryValueCallBacks
CFDictionaryValueCallBacks包含一组回调的 预定义结构,适用于当 a 中的值CFDictionary都是CFType派生对象时使用。

因此,在您的情况下,CFRetain()将值添加到字典时会在指针上调用。这会导致崩溃,因为指针未指向 CoreFoundation 对象。

您可以使用创建字典

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

相反,这样就不会对该值进行“引用计数”。

或者,您可以将指针包装成 aCFDataRef并将其放入字典中。

在这两种情况下,当稍后从字典中检索值时,指针仍然有效是您的责任。


这是一个简单的示例,您可以如何为自定义对象实现引用计数:

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;
}
于 2014-04-23T07:24:23.703 回答