initWithContentsOfFile:path] memory management when returns nil
[[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 开发者_Python百科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.
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.
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.
精彩评论