Cocoa CF内存分配示例
在阅读有关CF内存管理的Apple文档时,我看到了一个示例: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指向同一内存位置,则使
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
,我就永远不会认为该对象是有效的。