2010-11-08 120 views
0

這是一個簡單的應用程序,從我的資源文件夾獲取30張圖片,在viewDidLoad期間將它們放入NSMutableArray,然後根據加速度計數據更改圖片。我有一個來自IB的UIImageView覆蓋整個視圖,當加速度計更新其信息時,它將uiimageview.image交換爲差異圖。作品約10秒鐘,然後崩潰與此:我的iPhone應用程序中的內存泄漏在哪裏?

Program received signal: 「0」. 
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Unknown error loading shared library "/Developer/usr/lib/libXcodeDebuggerSupport.dylib") 

在這裏四處尋找後,它聽起來就像是一個內存泄漏。以下是我正在使用的代碼:

Interface: 
{ 
    UIAccelerometer *accel; 
    IBOutlet UIImageView *pic; 
    NSMutableArray *picArr; 
} 

Implementation: 

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

picArr = [[NSMutableArray alloc] init]; //array of pics to be used 
NSString *path = [[NSString alloc] init]; //dynamic path of images to save to array 

for (int i = 1; i <= 30; i++) 
{ 
    path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"nativity_test_%i", i] ofType:@"jpg"]; 

    [picArr addObject:[[UIImage alloc] initWithContentsOfFile:path]]; 

} 

accel = [UIAccelerometer sharedAccelerometer]; 
accel.delegate = self; 
accel.updateInterval = 0.5f; 

[path release]; 

pic.image = [picArr objectAtIndex:15]; 
} 

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration 
{ 

if(acceleration.y < 0.0f) //goes thru the tilted left pics 
{ 
    for (int i = 0; i <= 15; i++) 
    {      
     if(acceleration.y >= (-(15.0f-(double)i)/30.0f) && acceleration.y < (-(14.0f-(double)i)/30.0f)) 
     { 
      pic.image = [picArr objectAtIndex:i+1]; 
     } 
    } 
} 

else if(acceleration.y > 0.0f) //goes thru tilted right pics 
{  
    for (int i = 1; i <= 14; i++) 
     if(acceleration.y > ((double)i/30.0f) && acceleration.y <= ((double)(i+1)/30.0f)) 
     { 
      pic.image = [picArr objectAtIndex:i+15]; 
     } 
} 
} 

如果我遺漏了任何相關信息,請讓我知道。

+0

實例變量是不是屬性有關係嗎? – Marty 2010-11-08 23:15:07

回答

1

這不是由內存泄漏引起的崩潰,而是由內存過度釋放造成的。你的崩潰是由這一行造成的:

[path release]; 

刪除了這一行,你應該罰款。對於一些罰款的價值,無論如何;喬治所說的大部分內容也適用。

的原因是,被釋放的路徑將是這一個:

path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"nativity_test_%i", i] ofType:@"jpg"]; 

這是一個對象爲零的有效保留計數。雖然它有一個積極的保留計數,但它已經被自動釋放,並且在您返回到主事件循環時將被釋放。

你也應該刪除此行:

NSString *path = [[NSString alloc] init]; //dynamic path of images to save to array 

的原因是你使用它分配pathForResource的結果路徑,實際上從未。當然,您需要聲明路徑作爲變量。我建議將pathForResource行更改爲:

NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"nativity_test_%i", i] ofType:@"jpg"]; 

這是一個明智的改變,因爲在循環之外沒有理由需要這個。

你也應該解決這一行:

[picArr addObject:[[UIImage alloc] initWithContentsOfFile:path]]; 

[UIImage的頁頭]以1爲有效保留計數它添加到一個數組將增加兩個返回的UIImage。如果您稍後才發佈陣列,則會導致內存泄漏。相反:

[picArr addObject:[[[UIImage alloc] initWithContentsOfFile:path]] autorelease]; 

這將意味着你添加的UIImage爲0的有效保留計數的數組,這將其撞至1,使得數組對象的唯一所有者。之後陣列消失時,大部分圖像也會消失。 (imageView也將擁有分配給它的任何一個)

不要因爲這些東西而感到沮喪:有一天很快你會突然想到它,想知道爲什麼它會讓你頭痛。 :)

+0

嗯,我不再獲得內存警告,但它仍然崩潰。做出你所說的所有改變。難住了。可能只是放入30個不同的圖像視圖,並顯示/隱藏。馬虎,是的。 – Marty 2010-11-08 22:45:12

+0

試着打開NSZombieEnabled,它應該可以幫助你找到它。我認爲這是正確的方法,它應該是可以修復的。 – 2010-11-08 22:59:59

+0

由於某種原因,它可以在第三代iPod上正常工作,但不是我的iPhone 3G。都運行4.1。任何想法爲什麼? – Marty 2010-11-10 23:55:05

0

有一對夫婦的問題在這裏:

1)您還沒有釋放的UIImage對象您要添加到「picArr」。

這條線:

[picArr addObject:[[UIImage alloc] initWithContentsOfFile:path]]; 

應該是這樣的,而不是:

UIImage *image = [[UIImage alloc] initWithContentsOfFile:path]; 
[picArr addObject: image]; 
[image release]; 

我相信你也可以這樣做:

[picArr addObject: [[[UIImage alloc] initWithContentsOfFile:path] autorelease]]; 

2)你不需要做NSString * path = [[NSString alloc] init];你可以這樣做: NSString * path; 您正在給第一個循環內的路徑變量賦值,所以不需要alloc + init。一旦你改變這一點,你可以擺脫這行:

[path release]; 

3)我不知道你在哪裏釋放「picArr」本身,你需要。你可能已經在做,但沒有在你的文章中包含這一點代碼。

+0

我實際上已經與 [picArr addObject:[UIImage imageWithContentsOfFile:path]]; 但也沒有工作。我嘗試了你所說的也沒有奏效。 picArr在dealloc中獲得釋放,但是我將它用於程序的生命週期,所以我不想在執行期間釋放它。任何其他想法? – Marty 2010-11-08 22:13:23

+0

[picArr addObject:[UIImage imageWithContentsOfFile:path]]應該沒問題。我相信[路徑發佈];線路會導致問題。在我提供的答案中嘗試我的#2 ...只需使用NSString *路徑;並停止釋放「路徑」 – George 2010-11-08 22:17:51

+0

我得到內存警告1和2之前,它也崩潰了。我認爲它不在viewDidLoad中,因爲它使它很好,直到它將足夠的圖片換掉。我跑了儀器(第一次使用它),似乎每次圖片改變更多的記憶被採取。我以爲 pic.image = [picArr objectAtIndex:i + 1] 剛剛告訴圖片屬性在「pic」指向數組中的圖像對象。我不知道。 – Marty 2010-11-08 22:18:40