Objective-C:将自动释放的对象设置为nil

时间:2010-07-05 16:24:25

标签: objective-c

将自动释放的对象设置为nil是否安全?我知道我不需要释放自动释放的对象,但是如果我想立即释放对象以最小化内存使用,我可以将对象设置为nil吗?

我可能已经在某个地方读过这个,但我不记得在哪里,我想确保这样做是安全的。

2 个答案:

答案 0 :(得分:15)

我认为你错过了一些非常基本的东西。在内存管理方面,将对象设置为nil对您没有任何帮助。这是正在发生的事情:alt text http://gallery.me.com/davedelong/100084/Pointers1/web.png?ver=12783505480001

在此图像中,您拥有堆栈(您的本地变量存在的位置;它或多或少与执行时代码中当前位置的同义词)。如果您声明int bar = 42;之类的内容,则bar会存在于堆栈中。在右边你有堆。这是属于您的应用程序的全局内存空间。堆是为了解决范围问题而发明的:如何使有用的信息超出当前函数(或方法)的范围。当我们malloc空间时,我们会在堆上分配一个内存槽。当你alloc/init一个对象时,该对象就存在于堆上。在Objective-C中,所有对象都存在于堆中。*所以让我们考虑这一行:

MyObject * foo = [[MyObject alloc] init];

我们真的有两件事情在继续。第一个是我们已经在堆上分配了(alloc)一个新的空间块,其大小足以容纳MyObject结构。然后我们获取了那个块的内存位置,并将其分配给一个名为foo的局部变量。在上图中,左侧的红色圆圈为foo,右侧的红色圆圈为实际MyObject(及其所有数据)。到目前为止有意义吗?

以下是“将对象设置为nil”(foo = nil;)时会发生什么 alt text http://gallery.me.com/davedelong/100084/Pointers2/web.png?ver=12783505490001

您会看到对象仍然存在于堆中。事实上,唯一改变的是你的本地变量foo不再指向堆上的内存块。它指向0nilNULL,无论你想要什么称呼它,这就是我们如何表明“这不再指向任何相关内容”。

简而言之:将变量设置为nil与内存管理无关。如果您想立即删除对象,请使用release而不是autorelease。然而,即便如此,也不能保证“立即销毁”,因为其他东西可能是retain对象(这是使用保留释放内存管理模型的全部要点)。

除此之外,一旦你完成了一个对象(在你调用releaseautorelease之后),将变量设置为nil仍然是一个好主意。 ,只是为了避免潜在的问题。在Objective-C中,我们可以安全地向nil发送消息,而不会在我们的脸上爆炸(与Java不同)。但是,如果你不“忽略”一个变量,就会发生坏事。假设foo指向MyObject实例,然后MyObject实例被销毁(您release d,但未将其设置为nil })。如果您再次尝试在foo上调用某个方法,您的应用就会崩溃。如果您将foo设置为nil,那么您的应用将以愉快的方式继续。它可能不会你所希望的,但这完全是一个不同的问题。

欢迎来到Objective-C内存管理的精彩世界。

*除了本地块,但只有在它们被复制之前。还有一些其他的警告,但这是进入奥术。

答案 1 :(得分:0)

是的,这是一个很好的做法,因为它表明对象未使用 - 即没有引用数据。

对于它的价值,你会在Apple的示例代码中看到很多。