3

[[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 Answers2

1

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.

  • yes but if init returns nil, how must release the object? if I do UIImage* image = [[UIImage alloc] initWithContentsOfFile:path]; and image is nil, [image release] is the same as [nil release], and is not releasing the allocated object – Isidoro Aguilera Jul 05 '11 at 10:09
  • You don't need to release it as it is nil, although it doesn't hurt to call `[image release]` anyway as the image may not always be nil. Please don't use retain count to determine if an object is taking up memory as the two very different things; this is where I think you are getting confused. Please see the link I posted. –  Jul 05 '11 at 10:18
0

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.

Eiko
  • 25,601
  • 15
  • 56
  • 71
  • 2
    If alloc/init returns nil, there is no memory left that you need to release. Everything is fine. And calling release on nil won't hurt, which is convenient. – Eiko Jul 05 '11 at 10:15