In Objective-C you have to make sure that you match your alloc and retains with the appropriate number of release calls. Otherwise you might be leaking objects. Here’s an example that I faced today.
The normal pattern if you create an object that you then add to an array is the following:
Player *tmpPlayer = [[Player alloc] initWithName:player1Name.text color:[UIColor greenColor]];
[tmpArray addObject:tmpPlayer];
[tmpPlayer release]; |
Because adding an object to an NSArray causes the object to be retained you have to religiously follow any addObject with a release. You only want to keep the object retained once because when you later release the array, the array in turn releases all it’s objects and if the retain count is higher then 1 then these objects will leak. I.e. their dealloc won’t be called because they still have a retain count higher than zero.
To visualize the dance of alloc, init, retain, release and dealloc you could do the following:
- (id) initWithName:(NSString *)aName;
{
if (self = [super init])
{
self.name = aName;
NSLog(@"player %@ init, retain count is now %d", name, [self retainCount]);
return self;
}
return nil;
}
- (void) retain
{
NSLog(@"player %@ retain, retain count is now %d", name, [self retainCount]+1);
[super retain];
// cannot log here, causes crash
}
- (void) release
{
NSLog(@"player %@ release, retain count is now %d", name, [self retainCount]-1);
[super release];
// cannot log here, causes crash
}
- (void) dealloc
{
NSLog(@"player %@ dealloc", name);
[name release];
[super dealloc];
} |
As you can see it is easy to override retain, release and dealloc and inject an NSLog to output the current retainCount. But don’t leave those log statements in the final product! NSLog are executed even if you strip all other debug info via a release build and I have seen them dramatically decrease your app’s performance.
In my case today I had forgotten the release after the addObject and thus the Instruments tool showed a couple of bytes leak that I spent an hour looking for in the wrong place.