2011-10-20 61 views
2

我目前的編碼我的應用程序頻繁加載圖像(但不相同的圖像)。據我測試,沒有內存泄漏問題,但應用程序的內存使用量增加,因爲我加載不同的圖像。這意味着應用程序最終會在操作系統達到內存上限時被殺死。我通過儀器進行了檢查,發現NSConcreteData擁有大量內存。iphone如何管理內存的時候經常加載圖像

memory allocation after the view is dismissed

//from different thread, and pass data to main thread 
NSData *data = [[[NSData alloc] initWithContentsOfURL:url] autorelease]; 
//at main, data to uiimage 
imgView.image = [[[UIImage alloc] initWithData:data] autorelease]; 

當視圖被解僱,所有分配的回憶得到的回報堆,它似乎像的應用程序增加內存 我分配了的NSData保持在內存裏,因此,內存使用情況相比之前它加載圖像。我不確定這是否是正常行爲。 或者在不同的線程之間傳遞分配的內存是不好的做法?

回答

2

這可能或可能不會幫助您的確切情況,但這通常會通過密切關注您的autorelease堆棧增長而減少。你應該能夠通過在自動釋放池塊中包裝那些重創造者(來自url的數據,包含數據的圖像)來減少這個問題。

@autoreleasepool { work with large NSObjects here } 

,或者根據不同的系統,你必須部署:

NSAutoreleasePool * pool = [NSAutoreleasePool new]; 
work with large NSObjects here 
[pool release]; 

如果你可以使用@autoreleasepool,這樣做。它稍微好一點,因爲它直接與底層的autorelease棧進行交互。如果您需要向後兼容,請使用NSAutoreleasePool。在更高層次上,他們真正起到相同的作用,因爲您應該能夠在程序中交換其實現,而不會引入新問題。因此,在決定使用哪個操作系統時,它確實歸結爲您所定位的最小操作系統以及您爲項目指定的構建設置。

你應該換你的處理和大(或多個)分配的創作自動釋放塊,因爲自動釋放的對象發送釋放消息「在將來的某個時候」。通過顯式創建和銷燬autorelease池(並且通過使用autorelease的頻率較低),可以讓許多這些對象快速銷燬。

至於爲什麼除了在您的程序中不使用autorelease之外,爲什麼這樣做還不錯:客戶端和系統庫最終會將大/多個圖像/ NSData添加到autorelease池。自動釋放池是像(線程局部)堆棧 - 當你摧毀當地的游泳池,而做你的游泳池是在上面所有的自動釋放的消息將會實現,而自動釋放對象將收到釋放消息。

或者是不好的做法,通過不同的線程之間分配的內存?

請記住,您應該從主線程向您的UIKit和AppKit對象發送消息。在Cocoa中,許多庫可能會指定它們的線程模型。 NSData遵循Foundation的線程模型。目的並不明確線程安全的,但他們是安全的,如果你讀和/或在任何給定的時間從沒有超過一個線程寫的(即使用,使用鎖時,你需要在MT上下文中使用它,或者通過複製)。傳遞和共享數據/對象並不是一個壞習慣,有時它是必需的(或邏輯解決方案)。有一個小問題說它「不錯」:很多人不太瞭解多線程和共享資源(這對於許多人來說並不是一項微不足道的技能)。

+0

顯式聲明NSAutoreleasePool和只使用變量autoreleasepool之間的區別? – REALFREE

+0

@REALFREE評論/響應擴大並移到更新的答案。 – justin

1

嘗試這樣的事情。自動釋放不如明確釋放。

//on background thread data's retain count will now be 1 
NSData *data = [[NSData alloc] initWithContentsOfURL:url]; 


//on main thread (I'm assuming .image is a retained property) 
UIImage *newImage = [[UIImage alloc] initWithData:data]; 
imgView.image = newImage; 
[data release]; 
[newImage release]; 
0

嘗試打開分配來計算內存, ,當每次你想釋放的東西, 使它成爲第一,確保沒有人使用這個變量。 否則,它會崩潰。

在釋放之前使變量等於零。