EGOCache 源码解析

mmp7 10年前

今天说说一款叫 EGOCache 的开源项目,一个简单、线程安全的基于 key-value 的缓存框架,原生支持NSString、UI/NSImage、和NSData,也支持储存任何实现<NSCoding>协议的类,可以设定缓存过期时间,默认是 1 天;ARC、基于Block,同时支持 iOS 和 OSX 平台。

Fast Caching for Objective-C (iPhone & Mac Compatible)

EGOCache 是 Enormego 团队的开源作品,Enormego 在 Github 上贡献了众多开源项目,大家很可能用过 EGOTableViewPullRefresh ,它就是出自 Enormego 之手,可不知为何 EGOTableViewPullRefresh 在两年前就已经停止了更新;不过不用担心,今天本文所说的 EGOCache 还在保持着更新。

结构分析

EGOCache 保持很轻盈的体积,只有一个类,包括EGOCache.h和EGOCache.m两个文件,和最基本的操作,也很方便我们学习。

分区

提供了一个缓存分区的概念(姑且叫分区吧),可对复杂的项目进行缓存分区,基于文件的各个分区的缓存各不受影响,一个 EGOCache 实例就对应一个分区。可以让稍复杂的应用场景对不同的数据进行分类缓存,便于管理和统计。

建立分区

如果想要新建一个分区,可以使用initWithCacheDirectory:构造方法指定一个缓存目录来创建一个EGOCache实例,如果分区已存在,则会直接使用。

全局分区

EGOCache 贴心地提供了一个全局 EGOcache 单例,也就是一个默认分区,方便一些简单情况下的快速使用。调用globalCache实例方法就能获取到一个单例实例,就是所提供的默认缓存分区。

储存方式

EGOCache 采用磁盘储存方式缓存所有数据,且并没有提供内存缓存,所以如果你需要频繁读取某些缓存,为了加快读取速度和磁盘开销还是建议自己在内存中缓存一下。

上文说到分区的概念,每一个分区就对应一个EGOcache实例,同时对应一个 缓存目录,目录中就包含唯一一个.plist文件,这个 plist 文件中就存放了缓存文件对应的key和该项的过期时间,所以每个缓存目录结构大致如下:

MyCache      MyCache.plist      _abc      _def

过期

每缓存一个项,都可以单独为其设定一个过期时间,那检查这个过期时间并做删除操作的事件是在哪里触发的呢?

经过对源码的翻阅,在initWithCacheDirectory:方法里,即每次初始化实例对象的时候会扫描一遍plist文件中记录的所有已存在的缓存项,并和当前时间作比较,过期时间早于了当前时间则删除对应缓存文件,并删除 plist 文件中对应 key 的记录。

线程

大量使用了基于 GCD 的异步操作,在EGOCache类的构造中为每个实例维护了 3 个 GCD 队列:

dispatch_queue_t _cacheInfoQueue;  dispatch_queue_t _frozenCacheInfoQueue;  dispatch_queue_t _diskQueue;

从名字即可看到不同的队列对应不同的缓存相关操作,为了互不冲突。

安装

已加入 Cocoapods 豪华午餐,即刻享用:

pod 'EGOCache', '~> 2.1.3'

尾言

其实我在很早,几年前就用过这个开源库,当时被吸引的就是极为简单的操作方法,闲逛之下看到如今还保持着活跃更新,不久前又增加了需要支持 Swift 的nonnull、__nullable关键字,于是便写下一点点对此项目的一点理解。

来自:http://www.isaced.com/post-268.html