IOS Memory Management followup. dealloc vs nil

iosiphonememory-managementobjective c

With regards to this posting:
iPhone – dealloc – Release vs. nil

1) [foo release];
2) self.bar = nil;

The explanation was as follows:

  1. Is releasing the object, accessing it through the instance variable bar. The instance variable will become a dangling pointer. This is the preferred method in dealloc.

  2. Is assigning nil to a property bar on self, that will in practice release whatever the property is currently retaining. Do this if you have a custom setter for the property, that is supposed to cleanup more than just the instance variable backing the property.

Could someone please clarify the explanation for #1? Accessed through the instance variable bar ?

E.g I have set a private var in my object header as so:

SomeObject *oPointer;

I am not using a property setter with this pointer in the header file and it does NOT get synthesized when instantiate the object.

In my code, given certain conditions, I later have to allocate and assign this pointer to it's object.

obj = [[SomeObject alloc] initWith....];

So this is now accessed through the instance variable obj. I have a UIButton which is configured to RESET this object it's attached method deallocs it. I do this via:

[obj release];
obj = nil;

After all that explaining the question is, why do I also have to declare the obj = nil? The [obj release] call seems to also kill the pointer. I was thinking that [obj release] would deallocate the memory it's pointing to and also set obj to nil all in one shot but it seems it also kills the pointer because my app crashes when it tries to reference obj after [obj release];

Does this question make sense? Is the explanation simply that [obj release] does ALL cleanup, including killing the pointer and I need to be aware of that?

If I set a retain property for the SomeObject pointer would the pointer still be retained after release?

Thanks in advance!

Best Answer

Nil is preferable for two reasons:

  • nil is safe to call methods on, whereas a reference that has been released is not.

If it's a retain property, self.thinger = nil; will also call release. If not, it won't.

  • Whether you use retain or assign properties is code that you want to keep DRY, meaning that you don't want to have to switch anything but the assign/retain tag and be done. Using release in your deallocs has to be kept in sync with the properties.

If you use autorelease rigorously, you almost NEVER need to call release yourself except in custom setters for retain properties.

Check out the seminal article on NARC. Autorelease is your friend.

Related Topic