IOS 圖片存放3種方式

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,這樣的話就能夠保證圖片不會長期地存在在內存中json

  • 使用場景:因爲這種方法的特性, 因此 Resource 的方法通常用在圖片數據很大, 圖片通常不須要屢次使用的狀況,好比說引導頁背景(圖片全屏)緩存

  • 優點:圖片不會長期保存在內存當中, 因此不會有不少的內存浪費。同時, 大圖通常不會長期使用, 並且大圖佔用內存通常比小圖多了好多倍, 因此在減小大圖的內存佔用中, Resource 作的很是好bash

使用Bundle文件

  • Bundle 即資源文件包,將許多圖片,XIB,文本文件組織在一塊兒,打包成一個 Bundle 文件,方便在其餘項目中引用包內的資源。
  • Bundle 文件是靜態的,不參與項目的編譯Bundle 包中不能包含可執行的文件,它僅僅是做爲資源,被解析成爲特定的二進制數據。
  • 優點:Bundle 中文件不參與項目編譯,不影響App包的大小(可用於App的瘦身); 使用 bundle 方式方便對文件進行管理,方便在其餘項目中引用包內的資源。
  • 使用場景:較大的圖片,或者使用頻率較低的圖片
  • 讀取方式:使用 imageWithContentsOfFile 進行讀取,以下方法1;也能夠對 UIImage 進行擴展,以下方法2
  1. 使用 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"]];
複製代碼
  1. 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 裏的 2x3x,會根據具體設備分發,不會同時包含(App Slicing),而 Bundle 會都包含
  • xcassets 內,能夠對圖片進行 Slicing,即裁剪和拉伸,Bundle 不支持
  • Bundle 內支持多語言,xcassets 不支持
  • 此外,使用 imageNamed 建立的 UIImage,會當即被加入到 NSCache 中(解碼後的 Image Buffer),直到收到內存警告的時候,纔會釋放不在使用的 UIImage;而使用 imageWithContentsOfFile 建立的對象,每次都會從新申請內存,相同圖片不會緩存。所以,建議經常使用的、較小的圖,放在 xcassets 內管理,而大圖、使用頻率較低的圖,應該放在 Bundle 內管理
相關文章
相關標籤/搜索