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]; __POINTER = 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.