Setting object to nil after release -- TT_RELEASE_SAFELY
I have started to study Three20 and I have a simple question about TT_RELEASE_SAFELY
Up till now I like to write code in this way:
UILabel *lab = [[UILabel alloc] initWithFrame:rect];
[self.view addSubview:lab];
[lab release];
Here I think the main pool is responsible to free the memory of lab
.
Now I have found TT_RELEASE_SAFELY
which is defined like so:
#define TT_RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINT开发者_Python百科ER = nil; }
As you can see, after release, it sets the object to nil
.
I'd like to know the difference between the two ways and which way is better.
Thanks.
Sending a message to nil is valid in Objective-C. Sending a message to a deallocated object is not.
Sending a message to a deallocated object:
id obj = [[MyClass alloc] init];
[obj release];
[obj doSomething]; // Crash!
Sending a message to nil:
id obj = [[MyClass alloc] init];
[obj release], obj = nil;
[obj doSomething]; // Valid
Assigning nil to a variable after an object has been deallocated is controversial because it can prevent you from realizing that something is wrong. Sedate Alien's example:
[controlCenter dealloc];
...
float timeLeft = [controlCenter timeToWaitBeforeBombDetonation];
This code will crash since controlCenter has been deallocated. As a result this defect will be detected and fixed early.
[controlCenter dealloc], controlCenter = nil;
...
float timeLeft = [controlCenter timeToWaitBeforeBombDetonation];
This code will assign 0.0 to timeLeft which appears to be a valid wait time even though controlCenter is nil.
Take the above with a grain of salt, since if you are writing an Objective-C app, you are probably more concerned with keeping your users happy by avoiding crashes than destroying cities. If the latter is a concern, you should probably be using a type-safe language like Ada.
I believe that using these variants of "safe releases" is an expressly bad idea.
Your application will fail in silent and mysterious ways, as messages passed to nil
will not raise any warnings. It's much better to not nil out your references and take advantage of all that NSZombieEnabled
has to offer.
The only difference is that TT_RELEASE_SAFELY sets the pointer to nil after release, so the reference won't be used after release. The pattern is a good one to follow and the TT_RELEASE_SAFELY macro makes it simpler to implement.
精彩评论