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;
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
Hello Tariq
ReplyDeleteI must say your code is Very helpful.But I cant release the imageView.animatioImages property as my code is arc enabled which doesnt allow me use release and still I am getting crashes in my app.Please help.
Thanks
Mohit Jain