2011-03-26 108 views
1

我测试我的应用程序的工具, ,我看到我的UIImage和UIImageView的是内存泄漏想疯了......的UIImage和UIImageView的内存泄露

我基本上使用递归,所以相同的变量得到在每次通话中加载不同的图像。

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]; 

任何人都可以帮我吗?这是让我坚果..

我原来已释放所有dealloc变量,但它似乎没有进入dealloc,所以我也把它放在viewDidUnload和didReceiveMemoryWarning。

回答

1

我认为这个问题是这样的:

“我基本上使用递归,所以相同的变量得到每个加载不同的图像称为”

...再加上这样的:

“我最初已经释放了dealloc中的所有变量,但它似乎并没有进入dealloc,所以我也把它放在viewDidUnload和didReceiveMemoryWarning中。”

所以基本上,如果我正确理解你的代码,几次通过通过你的类的整个生命周期中的alloc/init部分,但只有一次调用release时,类本身被释放。我希望能够疯狂地泄漏。

您应该能够通过改变分配/初始化部分遵循类似的模式来解决这个问题:

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... 

这是假定这些变量都声明为你的类的实例变量,并在init你它们都设置为nil,像这样:

- (void) init { 
    if ((self = [super init])) { 
     //set default values 
     nextImageName = nil; 
     nextImageName2 = nil; 
     //and so on... 

     //do other setup things here 
    } 
} 
+0

你说得对!我分配了很多次,只发布一次...... Thanx! – CosmicRabbitMediaInc 2011-03-26 08:05:05

+0

您可能还想在下面加入Bastian的答案。他也提出了一个有效的观点。 – aroth 2011-03-26 08:08:21

1
nextImageName = [[NSString alloc] init]; 
nextImageName = [[currentPlayers objectAtIndex:playerIndex] retain]; 

有你有你的第一个memleak ..你分配一个字符串和T如果你用数组中的一个替换那个对象。

您可以简单地删除第一行..您不必在从数组中取出对象之前分配对象。

但没有看到更多的代码,我们不能看到你以后释放了什么......我希望你以后释放的东西;)

0

您分配和init'ing每个对象,然后增加再次保留计数。

任何时候你叫页头,复制,新的或保留......在保留对象的数目就会增加1。当您松开,保留计数下降1。所以,当你键入

nextImageName = [NSString alloc] init]; 

然后

nextImageName = [[currentPlayers objectAtIndex:playerIndex] retain]; 

nextImageName现在具有2的保留计数如果你只使用第二行,你将被罚款。你不需要分配一个新的对象,你只需要保留正在返回给你的那个对象。

同样,nextImageView和nextImageView2被分配两次,因此保留计数为2.您只需要进行第二次调用。

nextImageView = [UIImageView alloc] initWithImage:nextImage]; 

希望这会有所帮助。

+1

从技术上讲,这是不完全正确的。 nextImageName上的保留计数仍然是一个。如果您尝试释放它两次,该应用程序将崩溃。发生什么是他丢失了旧的nextImageName对象,并且没有办法让它恢复..所以它被泄漏了。 – Bastian 2011-03-26 07:35:42

+0

我明白你在说什么了。感谢您指出了这一点!仍在学习... – Jamie 2011-03-26 07:37:42

0

试试这个代码。它将清除UIImage和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);