1. 程式人生 > >iOS關於載入圖片的幾種方式選擇

iOS關於載入圖片的幾種方式選擇

最近在開發過程中遇到一些效能優化的東西,這次來說說關於圖片載入的效能優化和選擇。

大家都知道建立UIImage常用以下幾種方式

+ (nullable UIImage *)imageNamed:(NSString *)name;      // load from main bundle
#if __has_include(<UIKit/UITraitCollection.h>)
+ (nullable UIImage *)imageNamed:(NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection NS_AVAILABLE_IOS(8_0);
#endif

+ (nullable UIImage *)imageWithContentsOfFile:(NSString *)path;
+ (nullable UIImage *)imageWithData:(NSData *)data;

簡單說一下imageNamed(1),imageWithContentsOfFile(2),imageWithData(3)的區別,以下用1,2 ,3來代替。

On devices with high-resolution screens, the imageNamed:, imageWithContentsOfFile:, and initWithContentsOfFile: methods automatically looks for a version of the requested image with the @2x modifier in its name. If it finds one, it loads that image instead. If you do not provide a high-resolution version of a given image, the image object still loads a standard-resolution image (if one exists) and scales it during drawing. 

以上是蘋果文件說明,大概意思就是說第一種和第二種都能自動識別@2x,@3x等不同解析度的圖片

-------------------------------------------------------------------------------------------------

第一種(1)會提供一個快取,具體是在載入的時候快取到系統記憶體,使用的時候從快取中進行載入,但是過多的話會導致記憶體洩露等記憶體警告問題。

imageNamed:後面跟的不是圖片名稱,是圖片集合的名稱,所以關於[email protected][email protected]

等,只需要寫上前面的image,他們屬於一個image下的圖片集合,內部會根據螢幕解析度自動識別,並進行展示。

第二種(2)不為影象提供快取,以下filePath 和filePath2類似,區別在於後面跟上具體檔案,但是這兩種是根據檔案路徑去獲取的,就是說你是@2x,就只能獲取到@2x,沒有的話就沒辦法獲取;而filePath1是根據檔案路徑下相似的檔案集來獲取的,內部會自動識別@2x,@3x等

NSString *filePath = [[NSBundle mainBundle]pathForResource:@"hotBagImage" ofType:@"png"];
NSString *filePath2 = [[NSBundle mainBundle]pathForResource:@"hotBagImage" ofType:@"png" inDirectory:@"test.bundle"];
NSString *filePaht1 = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:@"test.bundle/hotBagImage.png"];

第三種(3)不為影象提供快取,從二進位制資料建立,利用NSData方式載入時,影象會被系統以資料方式載入到程式。當你不需要重用該影象,或者你需要將影象以資料方式儲存到資料庫,又或者你要通過網路下載一個很大的影象時,請儘量使用imageWithData的方式載入影象。

關於使用,重點說一下前兩種

1 .  這裡要說一下Assets.xcassets,屬於管理圖片的一個工程檔案,內部可以建立圖片集,icon集,啟動圖集等,能自動識別圖片解析度,使用的時候用imageNamed來獲取圖片,不能使用imageWithContentsOfFile。它是一個很好的圖片管理檔案,我們的一些小的icon或者圖片可以放置進來,我們的啟動圖等在這裡面管理還是比較方便,但是大量或者圖片過大的話還是不建議使用。

2 .  bundle,資源管理檔案。右鍵新增file中,iOS-Resource 中的setting bundle進行建立。我們可以在這裡放置大量的工程素材,方便統一查詢和管理。同樣可以把不同解析度的圖片素材都加進來。我們就可以用

NSString *filePaht1 = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:@"test.bundle/hotBagImage.png"];

UIImage *image = [UIImage imageWithContentsOfFile:filePaht1];

這種方式去獲取到圖片集合,不佔用系統記憶體,大大節省了記憶體,起到了效能優化,缺點如果資源素材多,會增加包的體積,但這種一般不可避免

3 .  就是建立檔案進行素材資源管理,這種類似bundle,但是不優於,包內部解碼有的是能獲取到這些資源。

優缺點:

 1. Assets.xcassets,我們一般使用這個比較方便,資原始檔不太大、不是很多的情況下並不會造成很大的效能問題。但是量大會增加系統記憶體,導致APP吃記憶體較多。

2.bundle ,這種適合大圖片,量大的資源素材。我們使用imageWithContentsOfFile去載入圖片,既能避免佔用大量記憶體,同時bundle又起到對資源的封閉儲存。缺點會增加包的體積,這點有時候對於我們並不是很大的影響

3.建立檔案管理,這類直接把資源素材新增到一個開放檔案中,可以使用imageWithContentsOfFile不佔用記憶體,但容易丟失。

以上三種,第一種不能使用 imageWithContentsOfFile獲取,他們都能使用imageNamed獲取,對於這幾種管理資源素材方式和載入方式可以根據不同情況進行選擇。

開發中難免會需要注意一些細節,來做到專案優化,後續更新其他常用並需要注意的地方,如有不足請留言修正。