开发者

Objective-C: Setting autoreleased objects to nil

Is it safe to set an autoreleased object to nil? I know I don't need to release an autoreleased object but if I want the object to be released immediately to minimize memory use, can I set the object to nil?.

I may have read this somewhere a while back,开发者_运维技巧 but I can't remember where and I want to make sure that it is safe to do that.


I think you're missing something pretty fundamental. Setting an object to nil does nothing for you in terms of memory management. Here's what's going on:alt text http://gallery.me.com/davedelong/100084/Pointers1/web.png?ver=12783505480001

In this image, you have the stack (where your local variables live; it's more or less synonymous to where you currently are in your code while executing). If you declare something like int bar = 42;, then bar lives on the stack. On the right you have the heap. This is global memory space that belongs to your application. The heap was invented to solve the problem of scope: how to make useful information live beyond the scope of the current function (or method). When we malloc space, we are assigned a slot of memory on the heap. When you alloc/init an object, that object lives on the heap. In Objective-C, all objects live on the heap.* So let's consider this line:

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

We really have 2 things going on. The first is that we have allocated (alloc) a new chunk of space on the heap that's large enough to hold a MyObject structure. Then we've taken the location of that chunk o' memory and assigned it into a local variable called foo. In the image above, the reddish circle on the left is foo, and the reddish blob on the right is the actual MyObject (along with all of its data). Make sense so far?

Here's what happens when you "set an object to nil" (foo = nil;) alt text http://gallery.me.com/davedelong/100084/Pointers2/web.png?ver=12783505490001

You'll see that the object still lives on the heap. In fact the only thing that has changed is that your local variable foo no longer points to the chunk of memory on the heap. It points to 0 (nil, NULL, whatever you want to call it), which is how we indicate that "this doesn't point to anything relevant any more".

In a nutshell: setting a variable to nil has nothing to do with memory management. If you want to get rid of an object immediately, then use release and not autorelease. However, even then that's not a guaranteed "destroy immediately", since something else might be retaining the object (which is the whole point of using the retain-release memory management model).

Beyond this, once you're done with an object (and after you've invoked either release or autorelease), it's still a good idea to set the variable to nil, just to avoid potential problems. In Objective-C we can safe send messages to nil without things blowing up in our faces (unlike Java). However, if you don't "nil out" a variable, bad things can happen. Let's say foo is pointing to a MyObject instance, and then the MyObject instance is destroyed (you released it, but didn't set it to nil). If you try to invoke a method on foo again, your app will crash. If you do set foo to nil, then your app will continue on its merry way. It might not do what you were hoping, but that's a different problem entirely.

Welcome to the wonderful world of Objective-C memory management.

* except for local blocks, but then only until they're copied. There are some other caveats to this as well, but that's getting into the arcane.


Yes, this is good practice as demonstrates that object is unused - i.e. no referenced data.

For what it's worth, you'll see it a lot in the sample code from Apple as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜