2013-05-29 22 views
1

我的應用程序中有一個奇怪的崩潰沒有任何跟蹤。這可能是一個內存相關的問題,但信息很少&我不知道如何繼續或修復它。如果不是儀器本來就沒有線索的話。iOS應用程序崩潰,而UIImage加載(虛擬內存未清理)

我有一個圖像數組(在這個例子中是一個大小爲2的數組),其中我加載一個圖像,創建一個圖像上下文&繪製並保存到數組中。每次調用該方法時,圖像數組對象都會被新內容替換。在儀器中,我看到在此方法調用&期間顯然在每個調用內存未被清除之後非常巨大的虛擬內存使用率因此崩潰&。該項目是ARC。我將在下面列出代碼。這就是我們需要重新創建這個問題。 (我使用的圖像大小約7MB,所以它更容易重新創建崩潰)。另外我使用的是iPad2設備。

+ (UIImage *)imageCopy:(UIImage *)src 
{ 
    UIGraphicsBeginImageContext(src.size); 
    [src drawAtPoint:CGPointZero]; 
    UIImage *r = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return r; 
} 

- (IBAction)buttonTouch:(id)sender 
{ 
    for (int i=0; i<2; i++) 
    { 
     if (i==0) 
     { 
      self.mImage = [UIImage imageNamed:@"LARGE_elevation.jpg"]; 
     } 
     else 
     { 
      self.mImage = [UIImage imageNamed:@"LARGE_elevation2.jpg"]; 
     } 
     // imageArray is a NSMutableArray with capacity of 2 
     [imageArray setObject:[ViewController imageCopy:self.mImage] atIndexedSubscript:i]; 
    } 
    ((UIImageView *)[self.view viewWithTag:100]).image = self.mImage; 
} 

這裏是一個儀器的屏幕,其中發生內存警告後第二次出現故障。

Instruments Screenshot

我沒有看到任何大的問題與「imagecopy的」的方法,我在這裏使用。

對此的任何幫助真的很感激。 感謝&乾杯,

+0

「我有個圖像陣列(在該示例的陣列大小2)我在哪裏加載圖片......「」我使用的圖片大小約7MB ......「顯然,這不是一個明智之舉。 –

回答

1

我發現這是一個循環參考問題。因此,當新內容替換數組中的舊內容時,過去的對象仍然存在。這是一個非常有趣的發現,因爲在內存泄漏分析器中,它表現出幾KB的數據泄漏,你不會懷疑這是因爲非釋放的虛擬內存只有幾百兆字節(MB)。

作爲一個非常抽象的例子。

ClassA 

@property (strong) ClassB *obj 

---------- 

ClassB 

@property (strong) ClassA *obj 

- (id)initWithA:(ClassA *)objA; 
---------- 

因此,當您刪除A時,兩個對象都不會被正確釋放。在我的情況下,即使CoreGraphics計算掛在虛擬內存中的大約200MB數據上,由泄漏分析器跟蹤的泄漏也只有幾KB。

修正是將ClassB中的A引用標記爲弱。

ClassB 

@property (weak) ClassA *obj 

- (id)initWithA:(ClassA *)objA; 

判決

  • 決不下估計了內存泄漏,無論多麼大或小&弧或MRC
0

這個問題可能是,該方法imageNamed:緩存加載圖像,顯然有沒有辦法後內存警告編程方式清除緩存。
而不是imageNamed:,你可以使用其他方法,如initWithData:不緩存圖像。你會發現一個詳細的討論here

+0

感謝您的輸入。但它仍然是一樣的結果。另外,從文檔中可以看出, 「此方法在系統緩存中查找具有指定名稱的圖像對象,並在該對象存在時返回該對象。如果匹配的圖像對象**尚未存在於緩存**中,則此方法從指定的文件加載圖像數據,將其緩存,然後返回結果對象。「 – nsuinteger

+0

我認爲問題在於imageNamed:緩存MULTIPLE圖像,並且不再需要圖像時不自動釋放內存。但是,如果您使用非緩存方法獲得相同的結果,那麼讓我們尋找另一個原因... –