views:

758

answers:

4

I am using single UIImageView object, allocated memory it once. But changing the image names multiple times. The question is that,

A) one UIImageView object,allocated once and never changed image name. e.g UIImageView *firstObj = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"blue.png"]];

B) another UIImageView object,allocated once and changed image names multiple times

e.g UIImageView *secondObj = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"blue.png"]];

//changed image name once,

secondObj.image = [UIImage imageNamed:@"green.png"];

 and so on....

which objects uses maximum memory or use equal memory?

which is the best way to use secondObj with minimum memory utilization?

please explain it briefly because i need to use number of image in my project and i want to avoid memory issue due to the images.

A: 

Hi,

I'm no great Objective-C expert but your usage in B looks like it should work without leaking. Since no other objects (other than the UIImageView) are retaining the UIImages, they should be released when they are replaced in the UIImageView and the garbage collector should do its work.

David

David Oakley
Thanks David, Can u explain it more briefly?
shreya
A: 

A UIImage created using +imageNamed: is autoreleased so it will go away. To give an example:

UIImage *image1 = [UIImage imageNamed:@"blue.png"]; //image1 has retain count 1
[myImageView setImage:image1]; //image1 is retained by UIImageView so has retain count 2

//run loop ends, all auto released objects are released and image1 now has retain count 1

//Later in app

UIImage *image2 = [UIImage imageNamed:@"green.png"]; //image2 has retain count 1
[myImageView setImage:image2]; //image1 is released and now has retain count 0, so the memory is freed, image2 now has retain count 2 as it is retained
Martin Pilkington
A: 

Since no other objects (other than the UIImageView) are retaining the UIImages, they should be released when they are replaced in the UIImageView and the garbage collector should do its work.

Keep in mind that there is no garbage collector on the iPhone. You can find more about that here:
StackOverflow:Is garbage collection supported for iPhone applicaions?

(This should actually be a comment to Davids answer but I don't have enough reputation yet)

weichsel
+3  A: 

Reformatting your code, your second example is:

UIImageView *secondObj = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"blue.png"]];
// changed image name once
secondObj.image = [UIImage imageNamed:@"green.png"];
// and so on....

This code is fine. When you assign an image to an instance of UIImageView, it will increase the image's retain count by one. If an image is already assiged, it will release it first.

Since [UIImage imageNamed:...] will give you an object already marked for autorelease, you can continue to assign images as shown in the example with no memory leaks. Once the UIImageView releases the existing image, it will be collected by an Autorelease pool.

In terms of minimising memory usage, the [UIImage imageNamed:...] method does store the image in a small amount of application-wide cache memory that you don't exert any direct control over. The cache does have an upper limit limit, but you can't flush it to reclaim memory, so using it will increase your memory footprint as you fetch new UIImages.

You may want to consider avoiding this cache by using [UIImage imageWithData:...] to load your images, which is discussed in the Stackoverflow question [UIImage imageNamed…] vs [UIImage imageWithData…].

Nick Ludlam
Others have pointed out that imageNamed: is very bad for memory consumption due to the cache issue. I would even manually initialize the UIImage with initWithData: and release it right after the UIImageView initialization or the changing of the UIImageView image, simply to avoid buildup in the autorelease pool.
Brad Larson