Possible Duplicate:
Why setting to nil after releasing?
Which of the following examples are correct? I've seen different programmers / apps doing this in different ways and I just really want to know what's the right way to releasing an object. Is it required to set the object to nil after releasing it?
Example
API *api_handle = [[API alloc] init];
[api callmethod];
[api release];
api = nil;
Or
API *api_handle = [[API alloc] init];
[api callmethod];
[api release];
In other words, is it necessary to set the object to nil after being released? If not, why do people do it? If so, what are the benefits of doing it?
It's not required per se but it's generally good practice if the variable you're using has a scope that extends past the -release
message.
No.
People do it because it stops you from accidentally sending a message to a deallocated object. Sending messages to nil always just returns 0/nil but sending a message to a deallocated object will cause SIGSEGV in the best case and other unpredictable hard to debug behaviour in other cases.
Depends on context.
- In dealloc?
A personal choice; some do, some don't. If you are in dealloc
, the object is already effectively dead. There should be no further method invocation on the object that does anything other than more deallocation.
Personally, I'll sometimes set 'em to 0x1 to ensure a crash. Very helpful in concurrent codebases.
- Anywhere else?
Set it to nil
. If you have an object reference in an instance (an instance variable) whose lifespan is decoupled from the object itself, then you should be retaining the object reference on assignment and both releasing and nilling it out when the instance is done with it.
This prevents crashes both due to dangling pointers and over-releases.
It also lets you do if (!transientObject) transientObject = ....
kind of lazy initialization without having a tracking variable (a BOOL or something).
It is not required, and I don't also think it's a good practice to set local variable to nil after releasing, but I also don't tag it as a bad practice.
Setting local variable to nil does surely keep you away from accidentally EXEC_BAD_ACCESS, but this kind of defect is easily detected by XCode built-in static analyzer and at run-time by NSZombieEnabled already.
Moreover, if you modifying your code and set a reference to nil prematurely, you will never see crash and your perceived logic of that piece of code might be incorrect because your code after that point is not executed as you think it would be, and it will never complain anything. And if you already release it at correct point, why bother setting it to nil? If you add more code after that point to do something later, it deserves to crash rather than silently skip it, for then you will know something went wrong.
精彩评论