3
votes

[[UIImage alloc] initWithContentsOfFile:path]

return nil when the method can't initialize the image. Then next code is not releasing the allocated UIImage, as image is nil in the [image release] line:

UIImage* image = [[UIImage alloc] initWithContentsOfFile:path];
if(image)
{
....
}
//Here image is nil and not releases allocated UIImage.
[image release];

Is this really a memory leak?

if init returns nil, how must release the object? if I do UIImage* image = [[UIImage alloc] initWithContentsOfFile:path];

and image is nil because init fails, [image release] is the same as [nil release]. Ok there's not an error, but is not releasing anything.

2

2 Answers

1
votes

Retain count in this example has nothing to do with whether or not the image is nil. You manually allocated the image using

UIImage* test = [UIImage alloc];

and therefore the retain count will be one until you manually release it, as you are the sole owner of that object.

See Memory Management Rules for more information on the subject.

0
votes

release on nil is a no-op, so always ok. And it won't leak as you didn't have an object to start with.

UIImage* test = [UIImage alloc];

test is already an UIImage object on its own (though you failed to initialize it at this line).

You really should always do alloc/init on the same line (and on the same variable) - or the code logic is really hard to follow. Your code generates only one object, and then assigns it to another variable.

This is the same, though much clearer:

UIImage* test = [[UIImage alloc] initWithContentsOfFile:path];
UIImage* image = test;
int n = [test retainCount]

Here it is obvious that test and image are the same object (and hence have the same retainCount). Whenever you release one of them, the the object goes away (unless you retain it before).

Please also note that retainCount is not something you should rely on or make much assumptions on. It often is misleading at best.