2011-03-26 38 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);