欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

IOS 图片存放3种方式的实现

程序员文章站 2023-11-22 12:47:40
image.xcassets 创建 .xcassets,以 image set 形式管理图片,添加图片后会生成对应的 content.json 文件 加入 @2x 和...

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 内管理

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关标签: IOS 图片存放