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 内管理
相关文章
相关标签/搜索