Strange releasing problem
I have got an strange problem but I am quite sure, for you it is not. If it is so, please help me or explain. I have an array of 39 UIImages which will be used for animating UIImageView. and after playing the animation, memory does not release.
- (void)viewDidLoad {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38];
for (int i=1; i<=39; i++) {
NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"];
UIImage *image = [[UIImage alloc]initWithContentsOfFile:path];
[path release];
[actionArray addObject:image];
[image release];
NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]);
}
imageView.animationImages = actionArray;
imageView.animationDuration = 4.0;
imageView.animationRepeatCount = 1;
[imageView startAnimating];
NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]);
[actionArray release];
[pool drain];
[imageView release];
[self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0];
[super viewDidLoad];
}
-(void)playAnimation2{
if ([imageView isAnimating]) {
[imageView stopAnimating];
}
NSLog(@"RetainCount ImageView %d",[imageView retainCount]);
}
there is no leaks discovered but the amount of memory allocated still is 24 mb.
or it is not so necessary ?
EDIT:
Sorry, my fault. Due to many changes of my code I've got lost in it. After analysing I get it! Thanks a lot!
The correct Code is:
- (void)viewDidLoad {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38];
for (int i=1; i<=39; i++) {
NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"];
UIImage *image = [[UIImage alloc]initWithContentsOfFile:path];
// [path release];
[actionArray addObject:image];
[image release];
NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]);
}
imageView.animationImages = actionArray;
imageView.ani开发者_如何学CmationDuration = 4.0;
imageView.animationRepeatCount = 1;
[imageView startAnimating];
NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]);
[actionArray release];
[pool drain];
[self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0];
[super viewDidLoad];
}
-(void)playAnimation2{
if ([imageView isAnimating]) {
[imageView stopAnimating];
}
[imageView removeFromSuperview];
imageView.animationImages = nil;
NSLog(@"RetainCount ImageView %d",[imageView retainCount]);
}
The problem was with [path release];
There are quite a few things wrong with this code. It is a wonder it runs at all.
First:
Do not use -retainCount.
The absolute retain count of an object is meaningless.
You should call release
exactly same number of times that you caused the object to be retained. No less (unless you like leaks) and, certainly, no more (unless you like crashes).
See the Memory Management Guidelines for full details.
Now, some of the problems:
You asked if you need to empty the array and then said array=nil; ... doesn't work. Setting an array reference to nil doesn't do anything to the array; doesn't release it or empty it.
you are overreleasing
path
you are loading a series of images, sticking 'em in an array, and there isn't anything in that code that is releasing the array (or emptying it). That your app continues to use the memory and shows no leaks sound like correct behavior.
Why are you releasing
imageView
? There is nothing in that code implying that you retained it and, even if it were retained via some other mechanism (IB?), that would be a really odd place to release it.
I think you need to remove all the objects from the array for it to work.
Try deleting the objects from the array, and then the array once you're finished with them.
You are releasing imageView
without retaining it anywhere, so there is probably something else wrong with you code. It seems however, that imageView
is retained by another object ( most likely the superview), which keeps it in memory. This will also keep the array of images in memory.
If you don't need imageView
anymore, remove it from its parent with [imageView removeFromSuperview];
As we already solved here: releasing problems
Set imageView.animationImages = nil;
Also, you need to remove the [path release];
or it will crash.
The Memory Management Guide is a vital place to start with.
Edit Never rely on the retainCount property!
Edit 2 Releasing imageView in that method is clearly a bug as well!
精彩评论