Reputation: 5301
With regards to this posting: iPhone - dealloc - Release vs. nil
1) [foo release];
2) self.bar = nil;
The explanation was as follows:
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.
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!
Upvotes: 3
Views: 5360
Reputation: 69787
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.
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.
Upvotes: 4
Reputation: 3108
Releasing the object still points to the same object. I always do both, ing the viewDidLoad, and the applicationDidFinishLaunching
Upvotes: 0
Reputation: 17958
[obj release];
Decrements the retain count on the object obj points to and potentially causes it to be deallocated. This does nothing to change the obj
pointer which continues to point to some location in memory.
obj = nil;
Sets the obj
pointer to nil. This is recommended but not required. If you do not do this but continue to use the obj
pointer then you are likely to accidentally try to access the memory location which used to hold the object you released above. If that object has been deallocate this will result in a crash, or at least unintended behavior. By setting obj
to nil you ensure that any future use of obj
will send messages to nil with the normal well defined behavior for that.
Upvotes: 3
Reputation: 2044
Calling release will decrease the reference count on obj. If the reference count goes to 0, then it will be deallocated. The pointer obj still points to the same memory location, but accessing it will likely cause the program to crash. Setting obj to nil is not strictly necessary, but reinforces the idea that obj is no longer valid. It can be useful when debugging, or later in the program if you want to optionally re-create obj and use a "if (obj != nil)" check to see if it's been created already.
If you set retain on it as a property, then when it's called as "self.obj = someObj", Objective C will add one to someObj's reference count. You should never call retain yourself on something that is created via alloc-init, since alloc-init already sets the reference count to 1. If you retained that object, then when it was released, the reference count would only go back to 1, and it would become a memory leak.
Upvotes: 3