iOS第三方库—源码分析iOS Developer闻道丶iOS(尝鲜版)

iOS源码解析—YYCache(概述)

2017-03-08  本文已影响345人  egoCogito_panf

概述

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类。

上一篇下一篇

猜你喜欢

热点阅读