0

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

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

它说释放是使用临时引用以防万一newTitle并且title指向相同的内存位置。但我不确定我是否理解如果它只是发布title然后创建一个副本会发生什么。

4

1 回答 1

4

问题是指针newTitletitle指针都可以指向相同的内存位置。

所以想象一下,如果你有它

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

它摆脱了临时变量,看起来更简单。这一切都很好。

但是如果你这样做了怎么办

SetTitle(title);

所以当你进入函数时,两者newTitletitle指向同一个地址!所以函数的第一行将释放title;但这也是同时发布newTitle的(因为它们是相同的!)。

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

所以函数的第二行将尝试制作垃圾内存的副本。如果你非常、非常、非常幸运,你的应用程序将会崩溃。但我很确定这最终会导致不确定的行为,所以如果你的电脑着火并开始唱“God Save The Queen”,你只能怪你自己。

在 Apple 的版本中,它将原件title放到一个临时变量中,创建副本,然后释放原件title。这很好,因为复制不会在垃圾数据上完成,并且您的计算机仍然非常幸福地没有着火。

双赢。

于 2013-05-25T17:34:24.830 回答