iOS开发笔记之七十二——一种轻量级的缓存方案MDEasyCache

******阅读完此文,大概需要5分钟******
一、简介
有人可能会问,无论是图片缓存还是文件缓存都有比较成熟的方案了,例如SDImageCache、TMCache/PinCache,为什么还要自己弄一套,其实这也是考虑到产品诉求的,我们公司对产品的轻量化有较高的要求。我们常常为了某个单一功能就会引入一个开源库进来,大部分代码逻辑用不到,而且一旦开源库出了bug,维护起来比较麻烦。所以在条件允许的情况下, 我会尽可能结合业务诉求,参考借鉴主流方案单独开发一套。

MDEasyCache是为了实现解决公司业务文件缓存的解决方案,它在业务中可以替代原来数据库缓存策略,它可以同时对图片和普通的对象进行缓存,属于一款轻量级、易使用、扩展性好的一款组件,github代码地址:

https://github.com/Leon0206/MDEasyCache.git

二、接入说明

1、文件的缓存,方法如下:
- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key;
- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key completion:(void(^)(MDEasyCacheConfig *config))completion;
其中object须为严格遵守NSCoding协议的对象,包括显式遵循NSCoding协议,实现如下两个方法;
- (id)initWithCoder:(NSCoder *)aDecoder;
- (void)encodeWithCoder:(NSCoder *)aCoder;
第二个方法,有个completion回调,如果想获取文件存储的url等信息,可以实现此block;
2、文件缓存的读取,方法如下:
- (id)objectForKey:(NSString *)key;
- (id)objectForKey:(NSString *)key completion:(void (^)(MDEasyCacheConfig *config))completion;
3、删除指定key的缓存的操作:方法如下:
- (void)removeObjectForKey:(NSString *)key;
4、清除内存缓存,方法如下
- (void)clearMemory;
此操作会将所有内存缓存清空,下次读取时,会直接访问磁盘文件缓存;

5、清除磁盘缓存,方法如下:
- (void)clearDisk;
此操作会清除所有的磁盘缓存文件,业务上层慎用;

6、注意事项
(1)XYEasyCache是一个线程安全的缓存操作;
(2)如果你存储的对象不是严格遵循NSCoding协议,将不会进行任何存储操作,因为内部有比较严格的判断;
(3)key值上层保证唯一,XYEasyCache内部严格根据key值来存储,包括图片,相同的key值下次存储会覆盖之前的cache;
(4)在收到内存MemoryWarning事件和进入后台DidEnterBackground事件时,会执行clearMemory操作;

三、原理与机制

1、内存缓存

XYEasyCache内部是维护了NSMutableDictionary字典数据结构,(考虑到NSCache的不稳定性,所以没用)
@property (strong, nonatomic, nonnull) NSMutableDictionary *memoryCache;
而且同时对于每个缓存,也会维护对应的cacheConfig字典数据结构,如下:
@property (strong, nonatomic, nonnull) NSMutableDictionary *cacheConfig;
目前config的字段还比较少,可以留给读者自己扩展。
2、磁盘缓存
XYEasyCache的文件缓存采取图片和文件分开的方式,图片的处理是先转为NSdata再存储,如下:
  [self.fm createFileAtPath:XYImageDiskCacheKeyPath(key) contents:imageData attributes:nil];
与此同时,普通数据类型的存储是采取NSKeyedArchiver的方式存储的,如下:
 [NSKeyedArchiver archiveRootObject:object toFile:XYDefaultCacheKeyPath(key)];
3、存储目录
为了便于管理和查询效率,文件缓存和图片缓存采取不同的存储目录,分别是:XYDefaultCachePath和XYImageDiskCachePath,

4、文件的缓存与读取流程
XYEasyCache在进行文件缓存时,会优先存储到内存:
  [self.memoryCache setObject:object forKey:key];
然后会在子线程里存储到磁盘,如下:
        dispatch_async(self.cacheQueue, ^{
            @synchronized(self) {
                if (![self setObjectToDisk:object forKey:key]) {
                    config.pathURL = nil;
                    NSLog(@"!!!Warning: Disk cache fail!!!");
                    dispatch_async(dispatch_get_main_queue(), ^{
                        if (completion) {
                            completion(config);
                        }
                    });
                } else {
                    NSLog(@"Disk cache success: %@",config.pathURL);
                }
            }
        });
文件读取时,会优先去内存中查找,如果查找不到,会去磁盘缓存中去查找,找到后会再写一份到内存中去;

5、内存缓存与磁盘缓存的清除
clearMemory操作会将内存缓存直接全部清除;
  [self.memoryCache removeAllObjects];
  [self.cacheConfig removeAllObjects];
磁盘缓存的清除会直接删除XYDefaultCachePath和XYImageDiskCachePath文件目录:
 [[NSFileManager defaultManager] removeItemAtPath:XYImageDiskCachePath error:&error2];

猜你喜欢

转载自blog.csdn.net/lizitao/article/details/80765123