iOS源码解析—YYCache(概述)

概述

YYCache是一个用来封装客户端缓存功能的库,实现了二级缓存的机制,即同时具备内存缓存和硬盘缓存的功能。

文件结构

YYCache主要分为YYCache、YYDiskCache和YYMemoryCache三个类,YYDiskCache实现了硬盘缓存的功能,YYMemoryCache实现了内存缓存的功能,YYCache类提供了通用的缓存存取的方法,内部调用YYMemoryCache和YYDiskCache的方法。

YYCache

下面是YYCache类的代码注释:

@interface YYCache : NSObject
  
@property (copy, readonly) NSString *name; //缓存路径名
@property (strong, readonly) YYMemoryCache *memoryCache; //内存缓存
@property (strong, readonly) YYDiskCache *diskCache; //硬盘缓存

//初始化
- (nullable instancetype)initWithName:(NSString *)name; //根据名称初始化
- (nullable instancetype)initWithPath:(NSString *)path; //根据路径初始化
+ (nullable instancetype)cacheWithName:(NSString *)name; //根据名称初始化
+ (nullable instancetype)cacheWithPath:(NSString *)path; //根据路径初始化
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;

//缓存中是否包含key对应的数据
- (BOOL)containsObjectForKey:(NSString *)key;
- (void)containsObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, BOOL contains))block;
//根据key查找并返回缓存中对应的数据
- (nullable id<NSCoding>)objectForKey:(NSString *)key;
- (void)objectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, id<NSCoding> object))block;
//想缓存中存入数据,设置key
- (void)setObject:(nullable id<NSCoding>)object forKey:(NSString *)key;
- (void)setObject:(nullable id<NSCoding>)object forKey:(NSString *)key withBlock:(nullable void(^)(void))block;
//删除key对应的缓存数据
- (void)removeObjectForKey:(NSString *)key;
- (void)removeObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key))block;
//清空所有缓存数据
- (void)removeAllObjects;
- (void)removeAllObjectsWithBlock:(void(^)(void))block;
- (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress endBlock:(nullable void(^)(BOOL error))end;

@end

YYCache主要提供了一系列操作缓存的方法,主要分为初始化、查找、存、取、删除几种。下面分别简单分析一下:

  1. 初始化

    核心方法是initWithName:name,该方法首先将将文件名name拼接在沙盒cache目录下面,作为YYCache创建缓存的路径,然后调用initWithPath:方法:

    - (instancetype)initWithPath:(NSString *)path {
        if (path.length == 0) return nil;
        YYDiskCache *diskCache = [[YYDiskCache alloc] initWithPath:path]; //创建硬盘缓存
        if (!diskCache) return nil;
        NSString *name = [path lastPathComponent];
        YYMemoryCache *memoryCache = [YYMemoryCache new]; //创建内存缓存
        memoryCache.name = name;
        
        self = [super init];
        _name = name; //缓存目录名称
        _diskCache = diskCache;
        _memoryCache = memoryCache;
        return self;
    }
    

    该方法根据路径path创建硬盘缓存对象diskCache,然后根据目录名称创建内存缓存对象memoryCache。

  2. 查找

    containsObjectForKey:方法判断内存或者硬盘中是否存在key对应的数据,代码如下:

    - (BOOL)containsObjectForKey:(NSString *)key {
        return [_memoryCache containsObjectForKey:key] || [_diskCache containsObjectForKey:key];
    }
    

    可能存在数据只在内存或者硬盘中出现的情况,所以逻辑上是或的关系。

  3. setObject: forKey:方法分别调用_diskCache和_memoryCache对象进行硬盘和内存的存储。

    - (void)setObject:(id<NSCoding>)object forKey:(NSString *)key {
        [_memoryCache setObject:object forKey:key];
        [_diskCache setObject:object forKey:key];
    }
    
  4. objectForKey:方法首先从内存中取数据,如果取不到,再从硬盘中取数据,并且把取到的数据存进内存中。

    - (id<NSCoding>)objectForKey:(NSString *)key {
        id<NSCoding> object = [_memoryCache objectForKey:key];
        if (!object) {
            object = [_diskCache objectForKey:key];
            if (object) {
                [_memoryCache setObject:object forKey:key];
            }
        }
        return object;
    }
    

    由于从硬盘中取需要I/O操作,所以内存中发现有数据,直接返回的逻辑在性能上会提升。

  5. 删除

    removeObjectForKey:方法分别调用_memoryCache和_diskCache的删除方法分别从内存和硬盘中删除数据。

    - (void)removeObjectForKey:(NSString *)key {
        [_memoryCache removeObjectForKey:key];
        [_diskCache removeObjectForKey:key];
    }
    

总结

通过代码分析,YYCache类实际都是调用_memoryCache和_diskCache来进行内存和硬盘的存取等操作,下文分别分析YYMemoryCache和YYDiskCache类。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容