2015年1月10日 星期六

[Objective-C] UIImage imageNamedvs imageWithContentsOfFile

很多人在使用UIImage類別時,可能會使用這個方法
+ (UIImage *)imageNamed:(NSString *)name
不過要注意的是,這個類別方法必須小心使用。

Apple的文件提到
This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method locates and loads the image data from disk or asset catelog, and then returns the resulting object. You can not assume that this method is thread safe.

簡單的說,他會先找系統快取(system caches)是否有這個圖片的物件,有的話就傳給你,沒有的話會從實際硬碟去找這個圖片物件,回傳給你並加入系統快取(system caches)。

這麼用的好處是,下次如果又需要這張圖片,他會從系統快取中找給你,速度較快。

但是,若是你的App大量地使用這個方法,把一些檔案較大的圖片都存入系統快取中,那可能會發生一些記憶體上的問題。

Apple的文件提到
If you have an image file that will only be displayed once and wish to ensure that it does not get added to the system’s cache, you should instead create your image using imageWithContentsOfFile:. This will keep your single-use image out of the system image cache, potentially improving the memory use characteristics of your app.

如果你不需要將此圖片存入系統快取,那麼可以使用這個方法
+ (UIImage *)imageWithContentsOfFile:(NSString *)path

這樣就不會存入系統快取中,不過缺點是每次都要去讀取實際的圖片,速度可能會比較慢一些。

簡單做個結論:

如果這張圖片必須時常使用,像是一些UI的圖片,那麼可以考慮使用imageNamed。

如果這張圖片檔案很大,或者是並沒有這麼常使用,那麼可以考慮使用imageWithContentsOfFile。

更懶一點,全部都用imageWithContentsOfFile。

要注意的是,imageWithContentsOfFile給的參數跟imageNamed不一樣。
imageNamed → 該圖片的名稱
imageWithContentsOfFile → 該圖片的路徑