IOS 圖片存放3種方式的實現
阿新 • • 發佈:2020-01-07
Image.xcassets
- 建立 .xcassets,以 Image Set 形式管理圖片,新增圖片後會生成對應的 content.json 檔案
- 加入 @2x 和 @3x 等倍圖後,打包後以 Assets.car 的形式存在,
- 使用 [UIImage imageNamed:@"xxx"] 方式讀取圖片,可以使用圖片快取 —— 相當於建立了一個 key-value的字典,key 為圖片名,value 為圖片物件。建立圖片物件後,該物件被加入到 NSCache 中(解碼後的 Image Buffer),直到收到記憶體警告的時候,才會釋放不在使用的圖片物件。 因此,對於需要在多處顯示的圖片,其對應的 UIImage 物件只會被建立一次(不考慮記憶體警告時的回收),減少記憶體消耗。
圖片直接加入工程中作為Resource
讀取方式:建立圖片 Resource 資料夾,直接將圖片加入到工程中,使用如下方式讀取圖片
NSString *path = [NSBundle.mainBundle pathForResource:@"xxx" type:@"png"]; UIImage *image = [UIImage imageWithContentsOfFile:path];
特性:在 Resource 的圖片管理方式中,所有的圖片建立都是通過讀取檔案資料得到的,讀取一次檔案資料就會產生一次 NSData 以及產生一個 UIImage。 當圖片建立好後銷燬對應的 NSData,當 UIImage 的引用計數器變為 0 的時候自動銷燬 UIImage,這樣的話就可以保證圖片不會長期地存在在記憶體中
使用場景:由於這種方法的特性,所以 Resource 的方法一般用在圖片資料很大,圖片一般不需要多次使用的情況,比如說引導頁背景(圖片全屏)
優勢:圖片不會長期儲存在記憶體當中,所以不會有很多的記憶體浪費。同時,大圖一般不會長期使用,而且大圖佔用記憶體一般比小圖多了好多倍,所以在減少大圖的記憶體佔用中,Resource 做的非常好
使用Bundle檔案
- Bundle 即資原始檔包,將許多圖片,XIB,文字檔案組織在一起,打包成一個 Bundle 檔案,方便在其他專案中引用包內的資源。
- Bundle 檔案是靜態的,不參與專案的編譯,Bundle 包中不能包含可執行的檔案,它僅僅是作為資源,被解析成為特定的二進位制資料。
- 優勢:Bundle 中檔案不參與專案編譯,不影響App包的大小(可用於App的瘦身); 使用 bundle 方式方便對檔案進行管理,方便在其他專案中引用包內的資源。
- 使用場景:較大的圖片,或者使用頻率較低的圖片
- 讀取方式:使用 imageWithContentsOfFile 進行讀取,如下方法1;也可以對 UIImage 進行擴充套件,如下方法2
使用 imageWithContentsOfFile 讀取
/// BSKDefine.h // bundle path #define STBundle_Name @"SafeToolResource.bundle" #define STBundle_Path [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:STBundle_Name] #define STBundle [NSBundle bundleWithPath:STBundle_Path]
/// usage #import "BSKDefine.h" UIImageView * headerBgImgView = [[UIImageView alloc] init]; headerBgImgView.image = [UIImage imageWithContentsOfFile:[SecKill_BUNDLE pathForResource:@"xxxx" ofType:@"png"]];
對 UIImage 進行擴充套件,建立 UIImage+BSKResources 類
/// UIImage+BSKResources.h NS_ASSUME_NONNULL_BEGIN @interface UIImage (BSKResources) + (UIImage *)bskImageNamed:(NSString *)imageName InBundleName:(NSString *)bundleName; @end NS_ASSUME_NONNULL_END
/// UIImage+BSKResources.m #import "UIImage+BSKResources.h" @implementation UIImage (BSKResources) + (UIImage *)bskImageNamed:(NSString *)imageName InBundleName:(NSString *)bundleName { NSString *resourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:bundleName]; NSBundle *resourceBundle = [NSBundle bundleWithPath:resourcePath]; return [UIImage imageNamed:imageName inBundle:resourceBundle compatibleWithTraitCollection:nil]; } @end
/// usage #import "UIImage+BSKResources.h" UIImageView * headerBgImgView = [[UIImageView alloc] init]; headerBgImgView.image = [UIImage bskImageNamed:@"xxx" InBundleName:@"BSKResources.bundle"]];
Bundle 和 xcassets 區別
- xcassets 裡面的圖片,只能通過 imageNamed 載入。Bundle 還可以通過 imageWithContentsOfFile 等方式載入
- xcassets 裡的 2x 和 3x,會根據具體裝置分發,不會同時包含(App Slicing),而 Bundle 會都包含
- xcassets 內,可以對圖片進行 Slicing,即裁剪和拉伸,Bundle 不支援
- Bundle 內支援多語言,xcassets 不支援
- 此外,使用 imageNamed 建立的 UIImage,會立即被加入到 NSCache 中(解碼後的 Image Buffer),直到收到記憶體警告的時候,才會釋放不在使用的 UIImage;而使用 imageWithContentsOfFile 建立的物件,每次都會重新申請記憶體,相同圖片不會快取。因此,建議常用的、較小的圖,放在 xcassets 內管理,而大圖、使用頻率較低的圖,應該放在 Bundle 內管理
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。