EGOCache如何检测缓存时间过期
来源:互联网 发布:和女生网络聊天技巧 编辑:程序博客网 时间:2024/04/20 06:20
子曰:学而不思则罔,思而不学则殆。
在上一篇文章中:EGOCache缓存框架详细讲解 提到EGOCache可以设定缓存过期时间,默认是1天。查看了一下EGOCache源码,设置默认时间:
[self setDefaultTimeoutInterval:86400]; //86400 = 24 * 60 * 60 刚好是一天时间。
EGOCache为什么要提供设定缓存过期时间呢?或者说设定缓存过期时间有什么好处呢?我觉得最大的好处就是可以定时清除缓存。可以设置某一项的缓存时间,很方便管理缓存。
那么问题来了:
EGOCache是怎么检测缓存过期时间的呢?
检测到时间过期之后,什么时候触发删除缓存项的?
带着这两个问题,我们来继续分析。
你会怎么实现
记得在公司里,老板经常会举这样的例子:
某某同志,刚来我们公司的时候,遇到问题就知道抱怨。从来不知道去思考怎么解决,只知道把问题抛给领导。工作半年下来,成长了很多。现在碰到问题,不仅把问题抛出来,而且还提供了自己的解决方案...
类似的例子,相信大家都听过。同样,既然前面我们提出这两个问题,我们也先来思考一下,如果我们来做该怎么解决?
如果让我来写的话,我脑海里初步实现方法有几个:
通过定时器来轮询,每隔一段时间检测一次。
写一个while循环来检测。
每次去读取缓存项的时候,判断缓存时间有没有过期。没过期,就返回读取的缓存项;否则,返回nil。
当然,还有一些方法,不一一例举了。仔细想想,这些方法弊端很容易显露出来。
为了小小的缓存时间,就用定时器轮询,显然是资源浪费
跟方法1差不多。
每次读取的时候判断是否过期,如果一直不读取,app的缓存会越来越大,也不可取。
这些方法都被排除了,还有好的方法吗?继续往下看:
EGOCache是怎么实现的?
仔细查看EGOCache源码,发现在initWithCacheDirectory:方法里,每次初始化EGOCache实例对象的时,会遍历一遍plist文件中所有已存在的缓存项,拿每个缓存项的时间和当前时间作比较,缓存项过期时间早于当前时间,则删除对应缓存文件,并删除 plist 文件中对应 key 的记录。
具体实现代码如下:
读取缓存项信息
_cacheInfo = [[NSDictionary dictionaryWithContentsOfFile:cachePathForKey(_directory, @"EGOCache.plist")] mutableCopy];if(!_cacheInfo) { _cacheInfo = [[NSMutableDictionary alloc] init];}
获取当前时间的NSTimeInterval
NSTimeInterval now = [[NSDate date] timeIntervalSinceReferenceDate];
声明removedKeys保存过期的缓存项对应的key
NSMutableArray* removedKeys = [[NSMutableArray alloc] init];
遍历缓存项信息并判断缓存时间
for(NSString* key in _cacheInfo) { //判断缓存项过期时间是否早于当前时间 if([_cacheInfo[key] timeIntervalSinceReferenceDate] <= now) { //如果缓存项过期时间早于当前时间,移除缓存项 [[NSFileManager defaultManager] removeItemAtPath:cachePathForKey(_directory, key) error:NULL]; //把过期的缓存项对于的key保存到removedKeys里面 [removedKeys addObject:key]; }}
删除过期缓存项对于的key
[_cacheInfo removeObjectsForKeys:removedKeys];
看到这些,是不是觉得人家思路特牛叉,反正,我是觉得这个作者不简单。到这一步就解决了吗?
EGOCache还做了什么?
细心的童鞋会发现:EGOCache是个单列类,也就是说整个程序应用周期只初始化一次。
+ (instancetype)globalCache { static id instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[[self class] alloc] init]; }); return instance;}
每次初始化的时候去判断了缓存项是否过期,这样做非常正确。思考一个场景:
用户打开app,EGOCache被初始化,并判断了缓存项是否过期。
如果刚好有一些缓存项在EGOCache被初始化之后过期。这个时候我们依然可以读到这个缓存项。这就不对了。
继续分析EGOCache源码发现,EGOCache在读取一个缓存项的时候,先判断缓存项是否存在,然后读取缓存项(注意:是读取EGOCache初始化的时候没有过期的缓存项,并没有说现在没有过期),最后去判断读取到的缓存项跟当前时间相比是否过期.
具体实现如下:
- (BOOL)hasCacheForKey:(NSString*)key { //读取EGOCache初始化的时候没有过期的缓存项 NSDate* date = [self dateForKey:key]; if(date == nil) return NO; //判断读取到的缓存项当前是否过期 if([date timeIntervalSinceReferenceDate] < CFAbsoluteTimeGetCurrent()) return NO; return [[NSFileManager defaultManager] fileExistsAtPath:cachePathForKey(_directory, key)];}- (NSDate*)dateForKey:(NSString*)key { __block NSDate* date = nil; dispatch_sync(_frozenCacheInfoQueue, ^{ date = (self.frozenCacheInfo)[key]; }); return date;}
EGOCache检测缓存时间过期的思路值得学习,以后遇到类似场景,完全可以借鉴。
- EGOCache如何检测缓存时间过期
- EGOCache如何检测缓存时间过期
- 缓存过期时间
- 第三方 缓存 EGOCache
- 缓存过期时间那些事儿
- EGOCache缓存框架详细讲解,egocache缓存框架
- EGOCache缓存框架详细讲解
- EGOCache缓存框架详细讲解
- EGOCache缓存框架详细讲解
- EGOCache缓存框架详细讲解
- Eacache缓存+缓存的过期时间
- 如何使用 EGOCache 来缓存和加载网页的速度更快
- 改进Smarty的缓存过期检测
- appache中的缓存过期时间设置
- varnish的全局缓存过期时间设置
- XMemcached的缓存过期时间问题
- 谈谈浏览器的缓存过期时间
- mongodb 设置过期时间 mongodb缓存
- RROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
- alertView中的属性和方法的讲解
- 【Java】检查二叉树是否平衡。
- Android主activity向自定义view传递参数
- SAP主数据管理
- EGOCache如何检测缓存时间过期
- poj 3667 Hotel (线段树 + 合并操作)
- 悟空学Linux专栏----第33篇
- android使用ViewPager实现底部菜单栏和左右滑动效果,加载多个Activity
- 悟空学Linux专栏----第34篇
- Altium Designer 3D封装下载及导入教程
- 如何判断android 网络连接是否可用
- 悟空学Linux专栏----第35篇
- osm文件导入PostGIS