前段時間完成的一個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/