2010-03-04 43 views
7

我使用儀器來查看內存泄漏。至少在一個場景中,我經常滑動幻燈片/頁面(在UIScrollView內),我沒有看到任何內存泄漏。使用儀器 - 在「分配壽命」下,我切換到查看「Created & Still Living」並在整個過程中看到大約1.17MB的記憶。我認爲這意味着我的應用程序只使用這麼多的實際內存,其餘部分正在被正確回收。內存警告和崩潰:如何處理

然而,在彈過100頁左右的頁面之後,我收到一條內存警告,然後我的一些視圖被卸載,導致整個應用程序崩潰。

如果我沒有使用大量內存並且沒有內存泄漏爲什麼我收到內存警告?由於沒有什麼我可以真正釋放,我沒有看到一種方法來避免崩潰。任何人都會遇到這種情況,或者知道我該怎麼辦?我是否誤解了樂器中的任何內容?非常感謝您的評論。

+0

沒有線索依然。也許'儀器'不能正確地報告我可能有的泄漏。是否有其他內存泄漏查找工具更可靠? – climbon 2010-03-05 15:34:49

回答

11

The documentation says:

如果匹配的圖像對象是不是已經在高速緩存中,這種方法加載從指定的文件中的圖像數據,高速緩存,然後返回生成的對象。

因此,使用imageNamed:加載的每個圖像在釋放最後一個所有權後都將繼續存在於緩存中。

儀器不會將此顯示爲泄漏,因爲嚴格來說,它不是一個:某些(UIImage)仍然知道這些圖像。泄漏儀器只會顯示存在但不知道的物體的泄漏。不過,你仍然可以在樂器中看到這一點。

  1. 在跟蹤文檔中選擇ObjectAlloc工具,並按當前計數或當前總大小對類列表進行排序。您會看到大部分內存被UIImage對象佔用。
  2. 如果將鼠標懸停在UIImage行的class-name列上,您會看到一個go(轉到iTunes Store)圖標;如果你點擊它,你會看到你的所有UIImage實例的列表。
  3. 然後,如果將鼠標懸停在實例行的地址列上,您將看到相同的按鈕;這一次,點擊它會將您帶到該地址的歷史記錄,包括該地址所有對象的創建,保留,發佈和釋放。在這裏,您可以看到圖像的分配(在UIImage類中,由您排序幾個堆棧幀),保留(由您)和發佈(由您)。你也可以看到它還沒有被UIImage釋放--緩存仍然擁有圖像,因此「泄漏」。

如果你不希望圖像堆放這樣,自己使用imageWithContentsOfFile:the -[NSBundle pathForResource:ofType:] method加載它們。我已經讀過,自從iOS 3以來,UIImage將會在至少一些內存不足的情況下清除它的緩存,所以這不應該像以前那樣是一個「泄漏」。你可能仍然會看到記憶堆積,但最終你會看到堆積物崩塌。如果你仍然看到內存堆積並且可以證明這是蘋果的錯,你應該記錄你的證據和file a bug

+0

百萬倍感謝! – RanLearns 2011-01-04 18:37:40

0

發現問題的根源。這是在下面的代碼片段

UIImage *image = [UIImage imageNamed:imageFile]; 

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)]; 

cartoon.image = image ; 
cartoon.backgroundColor = [UIColor brownColor]; 

我有圖像的100S加上每個頁面上的一些文字和用戶可以通過他們的手指輕彈(就像他們在iPhone中的照片應用做)滾動。我只在我的UIScrollView中創建3個頁面,並加載/卸載(也釋放)我明確分配的所有內容。因此,當發佈漫畫時,我只是發佈卡通UIImageView,而不是UIImage,它認爲它會被自動發佈。

但似乎它不是被自動釋放。我的應用程序獲取內存警告(我不採取任何行動),操作系統卸載我的視圖導致崩潰。

當我註釋掉兩行(下面的修改代碼片段)時,問題就消失了。沒有警告沒有崩潰。

//UIImage *image = [UIImage imageNamed:imageFile]; 

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)]; 

//cartoon.image = image ; 
cartoon.backgroundColor = [UIColor brownColor]; 

有誰知道如何解決這個問題?當警告發生時,有沒有辦法從UIImage強制釋放內存?

+0

它正在自動釋放。它也被其他東西所擁有。您可以通過查看Instruments中的單個UIImage實例來查看。 – 2010-03-06 22:23:12

2

您是否已將NSZombieEnabled環境變量設置爲yes?它會導致釋放對象留在內存中,因此不會讓你重新獲得內存。因此,如果激活,請嘗試禁用它。

1

您是否檢查過發佈所有IBOutlet對象? 在你的dealloc上,你應該釋放你擁有的任何IBOutlet對象,即使它們沒有合成方法。

我們有類似的問題,我們已經解決了它釋放所有IBOutlets。

Check this answer in Stack Overflow

1

如果你只有3頁我知道你正在重用的一些項目。

沒有剩下的代碼就很難說出了什麼問題,但也許你應該在創建一個新對象之前嘗試釋放卡通對象。

嘗試這樣:

IImage *image = [UIImage imageNamed:imageFile]; 

if (cartoon!=nil) 
    [cartoon release]; 

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)]; 

cartoon.image = image ; 
cartoon.backgroundColor = [UIColor brownColor];