UIImage & UIImageView memory leak
i'm testing my app on Instruments, and I see that my UIImage and UIImageView are memory-leaking like crazy...
I'm basically using recursion, so same variables get to load different images on each call.
nextImageName = [[NSString alloc] init];
nextImageName2 = [[NSString alloc] init];
nextImageName = [[currentPlayers objectAtIndex:playerIndex] retain];
nextImageName2 = [[currentPlayers objectAtIndex:(playerIndex+1)] retain];
nextImage = [[UIImage alloc] init];
nextImage2 = [[UIImage alloc] init];
nextImage = [UIImage imageNamed:nextImageName];
nextImage2 = [UIImage imageNamed:nextImageName2];
nextImageView = [[UIImageView alloc] init];
nextImageView2 = [[UIImageView alloc] 开发者_如何学运维init];
nextImageView = [[UIImageView alloc] initWithImage:nextImage];
nextImageView2 = [[UIImageView alloc] initWithImage:nextImage2];
NSLog(@"r:%d",currentRound);
NSLog(@"%d vs. %d", playerIndex, playerIndex+1);
buttonOne = [[UIButton alloc] init];
buttonTwo = [[UIButton alloc] init];
playerOne = nextImageView;
playerTwo = nextImageView2;
playerOne.frame = CGRectMake(180.0, 200.0, 275.0, 275.0);
playerTwo.frame = CGRectMake(550.0, 200, 275.0, 275.0);
buttonOne.frame = CGRectMake(180.0, 200.0, 275.0, 275.0);
buttonTwo.frame = CGRectMake(550.0, 200.0, 275.0, 275.0);
[buttonOne addTarget:self action:@selector(announceWinner:)
forControlEvents:UIControlEventTouchUpInside];
[buttonTwo addTarget:self action:@selector(announceWinner2:)
forControlEvents:UIControlEventTouchUpInside];
Could anyone please help me? This is driving me nuts..
I originally had release for all the variables at dealloc, but it seemed it didn't go into dealloc, so I also put it in viewDidUnload and didReceiveMemoryWarning.
I think the problem is this:
"I'm basically using recursion, so same variables get to load different images on each call"
...coupled with this:
"I originally had release for all the variables at dealloc, but it seemed it didn't go into dealloc, so I also put it in viewDidUnload and didReceiveMemoryWarning"
So essentially, if I understand your code correctly, you were making several passes through the alloc/init section over the lifetime of your class, but only ever calling release
once, when the class itself is deallocated. I would expect that to leak like crazy.
You should be able to fix it by changing the alloc/init section to follow a pattern like:
if (nextImageName) {
//if it was previously set, release it so that the old instance doesn't leak
[nextImageName release];
}
nextImageName = [[NSString alloc] init];
if (nextImageName2) {
[nextImageName2 release];
}
nextImageName2 = [[NSString alloc] init];
//and so on...
This assumes that these variables are all declared as instance-variables on your class, and that in init
you set them all to nil
, like so:
- (void) init {
if ((self = [super init])) {
//set default values
nextImageName = nil;
nextImageName2 = nil;
//and so on...
//do other setup things here
}
}
nextImageName = [[NSString alloc] init];
nextImageName = [[currentPlayers objectAtIndex:playerIndex] retain];
there you have your first memleak.. you are allocating a string and then you replace that object with the one one from the array.
you can simply remove the first line.. you don't have to allocate a object before getting one out of an array.
But without seeing more code we can't see what you are releasing later.. I hope you are releasing stuff later ;)
You are allocating and init'ing each object and then increasing the retain count again.
Anytime you call alloc, copy, new or retain...the retain count of the object goes up by 1. When you release, the retain count goes down by 1. So when you type
nextImageName = [NSString alloc] init];
and then
nextImageName = [[currentPlayers objectAtIndex:playerIndex] retain];
nextImageName now has a retain count of 2. If you only used the second line, you would be fine. You don't need to allocate a new object, you just need to retain the one that's being returned to you.
Likewise nextImageView and nextImageView2 are being allocated twice and therefore have a retain count of 2. You only need the second call you're making.
nextImageView = [UIImageView alloc] initWithImage:nextImage];
Hope this helps.
Try this code. It will clear the memory leaks on UIImage and UIImageView.
nextImageName = [NSString string];
nextImageName2 = [NSString string];
nextImageName = [[currentPlayers objectAtIndex:playerIndex] retain];
nextImageName2 = [[currentPlayers objectAtIndex:(playerIndex+1)] retain];
nextImage = [UIImage imageNamed:nextImageName];
nextImage2 = [UIImage imageNamed:nextImageName2];
nextImageView = [[UIImageView alloc] initWithImage:nextImage];
nextImageView2 = [[UIImageView alloc] initWithImage:nextImage2];
NSLog(@"r:%d",currentRound);
NSLog(@"%d vs. %d", playerIndex, playerIndex+1);
精彩评论