将自动释放的对象设置为nil是否安全?我知道我不需要释放自动释放的对象,但是如果我想立即释放对象以最小化内存使用,我可以将对象设置为nil吗?
我可能已经在某个地方读过这个,但我不记得在哪里,我想确保这样做是安全的。
答案 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
不再指向堆上的内存块。它指向0
(nil
,NULL
,无论你想要什么称呼它,这就是我们如何表明“这不再指向任何相关内容”。
简而言之:将变量设置为nil与内存管理无关。如果您想立即删除对象,请使用release
而不是autorelease
。然而,即便如此,也不能保证“立即销毁”,因为其他东西可能是retain
对象(这是使用保留释放内存管理模型的全部要点)。
除此之外,一旦你完成了一个对象(在你调用release
或autorelease
之后),将变量设置为nil
仍然是一个好主意。 ,只是为了避免潜在的问题。在Objective-C中,我们可以安全地向nil
发送消息,而不会在我们的脸上爆炸(与Java不同)。但是,如果你不“忽略”一个变量,就会发生坏事。假设foo
指向MyObject
实例,然后MyObject
实例被销毁(您release
d,但未将其设置为nil
})。如果您再次尝试在foo
上调用某个方法,您的应用就会崩溃。如果您将foo
设置为nil
,那么您的应用将以愉快的方式继续。它可能不会做你所希望的,但这完全是一个不同的问题。
欢迎来到Objective-C内存管理的精彩世界。
*除了本地块,但只有在它们被复制之前。还有一些其他的警告,但这是进入奥术。
答案 1 :(得分:0)
是的,这是一个很好的做法,因为它表明对象未使用 - 即没有引用数据。
对于它的价值,你会在Apple的示例代码中看到很多。