Cocoa CF内存分配示例

Cocoa CF内存分配示例,cocoa,core-foundation,Cocoa,Core Foundation,在阅读有关CF内存管理的Apple文档时,我看到了一个示例: static CFStringRef title = NULL; void SetTitle(CFStringRef newTitle) { CFStringRef temp = title; title = CFStringCreateCopy(kCFAllocatorDefault , newTitle); CFRelease(temp); } 它说,如果newTitle和title指向同一内存位置,则使

在阅读有关CF内存管理的Apple文档时,我看到了一个示例:

static CFStringRef title = NULL;
void SetTitle(CFStringRef newTitle) {
    CFStringRef temp = title;
    title = CFStringCreateCopy(kCFAllocatorDefault , newTitle);
    CFRelease(temp);
}

它说,如果
newTitle
title
指向同一内存位置,则使用临时引用进行释放。但是我不确定我是否理解如果它只是释放
标题
,然后创建一个副本会发生什么。

问题是
新标题
标题
都是指针,指针可以指向相同的内存位置

想象一下,如果你把它当作

static CFStringRef title = NULL;
void SetTitle(CFStringRef newTitle) {
    CFRelease(title);
    title = CFStringCreateCopy(kCFAllocatorDefault, newTitle);
}
它去掉了temp变量,看起来简单多了。那很好

但是如果你这样做了呢

SetTitle(title);
因此,当您进入函数时,
newTitle
title
都指向同一地址!因此,函数的第一行将释放
title
;但这也同时发布了
newTitle
(因为它们是一样的!)

因此,当它到达函数的第二行时,
newTitle
所在的内存已经消失。也许它被归零了。也许它被用来举行战争与和平的前几章。我们不知道,但我们知道它肯定不再是这个函数所期望的
newTitle
了,它本质上是垃圾内存

因此,函数的第二行将尝试创建垃圾内存的副本。如果你非常非常幸运,你的应用程序就会崩溃。但我很确定这最终会导致未定义的行为,所以如果你的电脑自焚并开始唱“上帝保佑女王”,你只能怪你自己

在苹果版本中,它将原始的
标题
放在一个临时变量中,创建副本,然后发布原始的
标题
。这很好,因为不会对垃圾数据进行复制,而且您的计算机仍然很幸运,不会着火


双赢。

问题在于
newTitle
title
都是指针,指针可以指向相同的内存位置

想象一下,如果你把它当作

static CFStringRef title = NULL;
void SetTitle(CFStringRef newTitle) {
    CFRelease(title);
    title = CFStringCreateCopy(kCFAllocatorDefault, newTitle);
}
它去掉了temp变量,看起来简单多了。那很好

但是如果你这样做了呢

SetTitle(title);
因此,当您进入函数时,
newTitle
title
都指向同一地址!因此,函数的第一行将释放
title
;但这也同时发布了
newTitle
(因为它们是一样的!)

因此,当它到达函数的第二行时,
newTitle
所在的内存已经消失。也许它被归零了。也许它被用来举行战争与和平的前几章。我们不知道,但我们知道它肯定不再是这个函数所期望的
newTitle
了,它本质上是垃圾内存

因此,函数的第二行将尝试创建垃圾内存的副本。如果你非常非常幸运,你的应用程序就会崩溃。但我很确定这最终会导致未定义的行为,所以如果你的电脑自焚并开始唱“上帝保佑女王”,你只能怪你自己

在苹果版本中,它将原始的
标题
放在一个临时变量中,创建副本,然后发布原始的
标题
。这很好,因为不会对垃圾数据进行复制,而且您的计算机仍然很幸运,不会着火


双赢。

谢谢你有趣有趣的解释。我的理解是CFRelease只是像autorelease一样标记要删除的对象。但是现在我知道,一旦我调用了
CFRelease
,我就永远不会认为这个对象是有效的。谢谢你有趣有趣的解释。我的理解是CFRelease只是像autorelease一样标记要删除的对象。但现在我知道,一旦我调用
CFRelease
,我就永远不会认为该对象是有效的。