在做 tomcat 小例子的時候,發現了這個問題,摘自官方文檔
+ (UIImage *)imageWithContentsOfFile:(NSString *)path
通過加載指定路徑(全路徑)中的文件,查找加載圖像數據,從而生成並返回一個圖形對象(或者 nil),但是僅僅是加載出圖像的對象,並不緩存這個圖形對象。
一般用法:
NSString *file = [[NSBundle mainBundle] pathForResource:name ofType:nil]; UIImage *image = [UIImage imageWithContentsOfFile:file];
其實,仔細看,很顯然,在文檔裡,官方是Creating New Images下面的方法介紹。僅僅是創建新圖片對象。
再看
imageNamed:inBundle:compatibleWithTraitCollection:
屬於目錄Cached Image Loading Routines下,是在包bundle中,通過匹配某特征(直接寫圖片名字即可),返回一個圖像,餅把圖緩存。
+ (UIImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle compatibleWithTraitCollection:(UITraitCollection *)traitCollection
參數分別是圖片名字,圖片在的包,用來描述希望生成的圖的特征的集合。這三個參數的此方法是 IOS8的新特性!如果找不到匹配的就返回 nil。
成功生成圖片對象之後,如果在內存裡這個生成的圖片緩存不存在了,那麼這個方法還是會去磁盤或者其他資源裡定位並加載這個圖片數據,返回。故,緩存一直存在!
此方法屬於線程不安全的!
這裡要看下這個
UITraitCollection
這個類是視圖管理器的一些特征、細節存儲的集合類,比如比例,尺寸等,當視圖控制器生成,那麼這個集合也自動為這個視圖控制器生成一個對象。當然,一些其他的類,比如 UIImage 類,也會擁有類似的功能去存相同的特征。
一個參數的
+ (UIImage *)imageNamed:(NSString *)name
返回的是圖形對象(或者nil),且有緩存,如果這個圖是第一次被加載,那麼這個方法會去app 的主包裡通過 name尋找這個圖片。這也就是為什麼,在往項目中拖拽圖片素材時,通常看選擇
1> Destination:勾選
2> Folders:
的不同,那麼使用的方法是受限制的。
因為選擇第一項:生成的黃色文件夾(區分點),在Xcode中分文件夾,但是在Bundle中所有素材都在同一個文件夾下,開發效率很高,因此,不能出現文件重名的情況,可以直接使用[NSBundle mainBundle]作為資源路徑,效率高!可以使用[UIImage imageNamed:]加載圖像。選擇第二項:生成藍色文件夾(特點),那麼Xcode中分文件夾,Bundle中同樣分文件夾,因此,可以出現文件重名的情況,那麼需要在[NSBundle mainBundle]的基礎上拼接實際的路徑,效率較差!且不能使用[UIImage imageNamed:]加載圖像。
同樣是線程不安全。
總得來說,使用大的圖片,如果不是常用,那麼用 imagewithcontentsoffile 方法,比較小的(比如圖標),需要經常使用的,那麼用後者,imageNamed 加載。內存常駐,效率高。不過,就如 tomcat 裡,那麼多圖片,一起用 imagenamed 加載,很容易內存洩露,程序崩潰,還需要及時關閉動畫,清除圖片數組等措施。
暫時了解下,以後有新發現再看。