iOS细节知识收录中高级iOS面试题精华集锦

iOS 图片缓存框架的设计

2020-05-11  本文已影响0人  Rockerliang

图片缓存框架

image.png

图片的读写

(1)如果程序并没有被关闭,一直在运行,那么此时内存缓存中有数据,硬盘缓存中有数据。如果此时再次请求数据,直接使用内存缓存中的数据即可
(2)如果程序重新启动,那么此时内存缓存已经消失,没有数据,硬盘缓存依旧存在,还有数据。如果此时再次请求数据,需要读取内存中缓存的数据。

Manager

是一个单例,用来暴露出缓存框架的接口,主要的接口有:

暂时不支持: 主要是实时下载图片的时候线程的一些状态的回调和设置

内存缓存

使用NSCache

NSCache的使用很方便,提供了类似可变字典的使用方式,但它比可变字典更适用于实现缓存,最重要的原因为NSCache是线程安全的,使用NSMutableDictionary自定义实现缓存时需要考虑加锁和释放锁,NSCache已经帮我们做好了这一步。其次,在内存不足时NSCache会自动释放存储的对象,不需要手动干预,如果是自定义实现需要监听内存状态然后做进一步的删除对象的操作

模拟器收到系统的内存警告,NSCache并不会清理,这里是需要主动注册一个内存警告用于清理内存缓存:

@interface AutoPurgeCache : NSCache
@end

@implementation AutoPurgeCache

- (nonnull instancetype)init {
    self = [super init];
    if (self) {
#if SD_UIKIT
        //收到系统内存警告后直接调用 removeAllObjects 删除所有缓存对象
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
#endif
    }
    return self;
}

- (void)dealloc {
#if SD_UIKIT
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
#endif
}

@end

磁盘缓存

  1. Caches:
    一般存储的是缓存文件,例如图片视频等,此目录下的文件不会再应用程序退出时删除。
    在手机备份的时候,iTunes不会备份该目录。
    例如音频,视频等文件存放其中
  2. Preferences:
    保存应用程序的所有偏好设置iOS的Settings(设置),我们不应该直接在这里创建文件,
    而是需要通过NSUserDefault这个类来访问应用程序的偏好设置。
    iTunes会自动备份该文件目录下的内容。
    比如说:是否允许访问图片,是否允许访问地理位置......

网络请求

NSOperation的串并行是通过设置最大并发数maxConcurrentOperationCount来实现的。

当maxConcurrentOperationCount为1时,就是串行执行
当maxConcurrentOperationCount > 1时,就是并行执行

图片解码解压缩

图片加载的工作流

概括来说,从磁盘中加载一张图片,并将它显示到屏幕上,主要工作流如下:

a.分配内存缓冲区用于管理文件 IO 和解压缩操作;

b.将文件数据从磁盘读到内存中;

c.将压缩的图片数据解码成未压缩的位图形式,这是一个非常耗时的 CPU 操作;

d.最后 Core Animation 使用未压缩的位图数据渲染 UIImageView 的图层。

在上面的步骤中,我们提到了图片的解压缩是一个非常耗时的 CPU 操作,并且它默认是在主线程中执行的。那么当需要加载的图片比较多时,就会对我们应用的响应性造成严重的影响,尤其是在快速滑动的列表上,这个问题会表现得更加突出。

在将磁盘中的图片渲染到屏幕之前,必须先要得到图片的原始像素数据,才能执行后续的绘制操作,这就是为什么需要对图片解压缩的原因。

解决方案:
当未解压缩的图片将要渲染到屏幕时,系统会在主线程对图片进行解压缩,而如果图片已经解压缩了,系统就不会再对图片进行解压缩。因此,也就有了业内的解决方案,在子线程提前对图片进行强制解压缩。
而强制解压缩的原理就是对图片进行重新绘制,得到一张新的解压缩后的位图。其中,用到的最核心的函数是CGBitmapContextCreate

图片解码的时机:

避免在主线程解压缩、解码,避免卡顿

上一篇下一篇

猜你喜欢

热点阅读