management

2. UIImage Tips…

There are several things which we need to keep in mind when we use UIImage as follows:
1. UIImage has 4 class methods to create its autorelease instance and 3 instance methods to load image.

2. When you want to cache the image, so that it can be easily loaded in no time whenever required, you should use:
UIImage *tempImage=[UIImage imageNamed:”test.png”]; where test.png is the image which will get cached at the first time and will remain in the memory untill app exits. But this should be used only when the image is less in memory size, otherwise your app will have less real and virtual memory for further use. This returns autorelease instance of UIImage that means you do not need to care about its release.

3. When you want to load the big memory sized images you should use:
UIImage *tempImage=[UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”test” ofType:@”png”]];
this will not cache the image in the memory for the next time use i.e. when you again load this image this will be loaded from file.

4. When you don’t want autorelease instance i.e you want to manage its alloc free things on your own you should use:
UIImage *tempImage=[[UIImage alloc] initWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”test” ofType:@”png”]];
but you have to release it when you are done with it as follows:
[tempImage release];

5. Whenever you set the UIImage’s instance to UIImageView’s image property, the retain count of UIImage’s instance increases by 1. So never forget to nil the UIImageView’s image property when you are done with it otherwise the UIImage will remain in the virtual memory and will leak.
Example:
UIImageView *imgView=[[UIImageView alloc] initWithImage:tempImage];
//now tempImage’s retain count will get increase by one. So nil the imgView’s image property whenever you are done with tempImage like this:
imgView.image=nil;

The difference b/w autorelease and normal instance is that we have to release the normal instance by calling release method to free up the memory.

1. UIImageView AnimationImages Memory Leak Mistry Solved:

We all know that to do animation using UIImageView, we load images in the NSArray and then set it to animationImages property of UIImageView and then call function startAnimating.
But when you try to repeat animation by loading again and again with different images using this method, you start experiencing Crash on iPhone device with status 101 at Xcode debug. Again, we all know why it crashed, just because of no more memory available for our app in the iPhone device.
But where did our memory went. Here is the answer for that. Every time when we set NSArray to animationImages, the whole data gets copied to it because animationImages is copy property of UIImageView. And if we try to again set same animationImages with some other NSArray, we try to nil it first then set with new array. But here we are wrong, when we nil this property, the real time memory decreases but the virtual memory doesn’t decrease because garbage collector is not there.
So instead nil we should call release method of this property which will force it to get freed from the virtual memory too. One more thing you should remember, don’t call release method of this property or don’t try to nil this property in dealloc method where your UIImageView’s reference is released, otherwise either you will get Bad Parameter warning or again virtual memory will not get freed.

Sample code:
UIImageView *imgView;

NSArray *firstArray, *secondArray;

firstArray= [NSArray arrayWithObjects:[UIImage imageWithContentOfFile: [[NSBundle mainBundle] pathForResource:@”1″ ofType:@”png”]], [UIImage imageWithContentOfFile: NSBundle mainBundle] pathForResource:@”2″ ofType:@”png”]], [UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”3″ ofType:@”png”]], nil];

secondArray=[NSArray arrayWithObjects:[UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”11″ ofType:@”png”]],[UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”22″ ofType:@”png”]], [UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”33″ ofType:@”png”]], nil];

imgView=[[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
[imgView setAnimationImages:firstArray];
[imgView setAnimationDuration:1];
[imgView setAnimationRepeatCount=0];
[imgView startAnimating];
[self addSubview:imgView];

After Some time, some where in your code u want to change the animation, then you should do as follows

[imgView.animationImages release];
[imgView setAnimationImages:secondArray];
[imgView setAnimationDuration:1];
[imgView setAnimationRepeatCount=0];
[imgView startAnimating];

And At the dealloc method you should do as follows:
[firstArray release];
firstArray=nil;

[secondArray release];
secondArray=nil;

[imgView removeFromSuperView];//If you not already removed this from super view.
[imgView release];
imgView=nil;

So, if you try this you will definitely gain your virtual memory and you app will never crash due to low memory. Any suggestions are always appreiciated.

Thanks,
Sanniv.