天天看點

萬惡的imageNamed

前段時間完成的一個iPad應用,近來測試發現一個問題,在iPad運作大量其他應用程式時很容易出現内容警告而導緻程式退出。找了一些資料,發現用起來友善的+ (UIImage *)imageNamed:(NSString *)name,卻存在一個很嚴重的記憶體釋放問題,它所占用的内容不被釋放,即使其所在的view已經release了。看完之後一陣後怕,皆因程式中使用UIImage基本都是使用這種方法擷取。事不宜遲,馬上對代碼進行優化。由于手頭暫時沒有裝置測試,測試效果稍候再分析。

轉載一篇很好的文章:

+ (UIImage *)imageNamed:(NSString *)name導緻的記憶體問題

這種方法在application bundle的頂層檔案夾尋找名字的圖象 , 如果找到圖檔, 系統緩存圖象。圖檔内容被加載到系統記憶體中,使用時直接引用到系統記憶體。 

是以當圖檔比較大時,程式使用的記憶體會迅速上升導緻記憶體警告并退出。 

特别在使用Interface Builder建立界面時,如果直接拖動UIImageView 并設定image的圖檔名稱。InterfaceBuilder 正是通過UIImage 類的imageName方法加載圖檔。圖檔被緩存,導緻記憶體使用較大。且無法釋放,即使release掉 UIImageView也無濟于事。 

是以推薦使用+ (UIImage *)imageWithContentsOfFile:(NSString *)path方法加載圖檔。 

也可以重載 imageNamed方法。 

@implementation UIImage(imageNamed_Hack) 

+ (UIImage *)imageNamed:(NSString *)name { 

return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] bundlePath], name ] ];

@end 

Note: With this override you will not have any cache loading UIImages, if you need this, 

you will have to implement your own cache. 

Tip: If your applications use much image processing, consider to use de PhotoshopFramework 

for iPhone. Check here: http://sourceforge.net/projects/photoshopframew/