子曰:学而不思则罔,思而不学则殆。

在上一篇文章中:EGOCache缓存框架详细讲解 提到EGOCache可以设定缓存过期时间,默认是1天。查看了一下EGOCache源码,设置默认时间:

    [self setDefaultTimeoutInterval:86400];//86400 = 24 * 60 * 60 刚好是一天时间。

EGOCache为什么要提供设定缓存过期时间呢?或者说设定缓存过期时间有什么好处呢?我觉得最大的好处就是可以定时清除缓存。可以设置某一项的缓存时间,很方便管理缓存。

那么问题来了:

  1. EGOCache是怎么检测缓存过期时间的呢?
  2. 检测到时间过期之后,什么时候触发删除缓存项的?

带着这两个问题,我们来继续分析。

你会怎么实现

记得在公司里,老板经常会举这样的例子:

某某同志,刚来我们公司的时候,遇到问题就知道抱怨。从来不知道去思考怎么解决,只知道把问题抛给领导。工作半年下来,成长了很多。现在碰到问题,不仅把问题抛出来,而且还提供了自己的解决方案...

类似的例子,相信大家都听过。同样,既然前面我们提出这两个问题,我们也先来思考一下,如果我们来做该怎么解决?

如果让我来写的话,我脑海里初步实现方法有几个:

  1. 通过定时器来轮询,每隔一段时间检测一次。
  2. 写一个while循环来检测。
  3. 每次去读取缓存项的时候,判断缓存时间有没有过期。没过期,就返回读取的缓存项;否则,返回nil。

当然,还有一些方法,不一一例举了。仔细想想,这些方法弊端很容易显露出来。

  1. 为了小小的缓存时间,就用定时器轮询,显然是资源浪费
  2. 跟方法1差不多。
  3. 每次读取的时候判断是否过期,如果一直不读取,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;
}

每次初始化的时候去判断了缓存项是否过期,这样做非常正确。思考一个场景:

  1. 用户打开app,EGOCache被初始化,并判断了缓存项是否过期。
  2. 如果刚好有一些缓存项在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检测缓存时间过期的思路值得学习,以后遇到类似场景,完全可以借鉴。

作者李刚是刚刚在线(www.superqq.com)站长,百度百家专栏作者
iOS工程师非著名自媒体,微信公众号iOS开发:iOSDevTip运营者

EGOCache如何检测缓存时间过期相关推荐

  1. redis缓存失效时间设为多少_Redis有效时间设置及时间过期处理

    本文对redis的过期处理机制做个简单的概述,让大家有个基本的认识. Redis中有个设置时间过期的功能,即对存储在redis数据库中的值可以设置一个过期时间.作为一个缓存数据库,这是非常实用的.如我 ...

  2. Powershell检测AD账户密码过期时间并邮件通知

    转自:http://lixiaosong.blog.51cto.com/705126/1409113 此脚本主要实现了两个功能 : 一能判断账户密码的过期时间并通过邮件通知到账户,二是将这些即将过期的 ...

  3. redis缓存失效时间设为多少_java操作Redis缓存设置过期时间的方法

    关于Redis的概念和应用本文就不再详解了,说一下怎么在java应用中设置过期时间. 在应用中我们会需要使用redis设置过期时间,比如单点登录中我们需要随机生成一个token作为key,将用户的信息 ...

  4. 封装一个可以设置微信小程序的本地缓存接口过期时间的方法!

    微信小程序提供的本地缓存api是个好东西,但是没有明确指定缓存有效期,对于某些应用来说,需要改造一下,方法思路很简单,也很常见通用的一个封装函数方法! 实现 新建wxCache.js /*** 本地缓 ...

  5. 如何用java操作Redis缓存设置过期时间

    如何用java操作Redis缓存设置过期时间?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获. 在应用中我们会需要使用red ...

  6. ehchache验证缓存过期的api_Ehcache缓存时间设置

    timeToLiveSeconds和timeToIdleSeconds timeToLiveSeconds=x:缓存自创建日期起至失效时的间隔时间x: timeToIdleSeconds=y:缓存创建 ...

  7. nginx php 缓存时间,nginx expires设置数据过期时间

    配置: location ~* \.(jpeg|jpg|png)  { expires 1d; } 设置缓存时间的格式: expires 1s; #1秒钟 expires 1m; #1分钟 expir ...

  8. redis 失效时间单位是秒还是毫秒_Redis有效时间设置及时间过期处理

    本文对redis的过期处理机制做个简单的概述,让大家有个基本的认识. Redis中有个设置时间过期的功能,即对存储在redis数据库中的值可以设置一个过期时间.作为一个缓存数据库,这是非常实用的.如我 ...

  9. 如何设置静态内容缓存时间

    百度的站长平台,大家可以多多关注一下.上面都有些基本的优化建议.对于想优化却不知道从什么地方下手的朋友,可以先解决上面提到的问题. 今天来说说"页面优化建议"里的"设置静 ...

最新文章

  1. 【天线】天线基础:名词解释
  2. 再探@font-face及webIcon制作
  3. 无线网卡掉线解决办法
  4. 数据可视化实战,画个新冠肺炎地图
  5. php libxml 宝塔,宝塔编译安装各个版本php无法安装
  6. 07-狄克斯特拉算法
  7. Oracle创建表空间及用户
  8. pytorch学习笔记(一):Tensor(张量)
  9. 亮度 调整_显示器对比度多少合适 显示器亮度多少合适【详细介绍】
  10. 大气压力换算公式_大气压强计算新方法
  11. 公司官网建站笔记(四):从阿里云将域名转出,并将域名转入腾讯云
  12. H3CV7交换机WEB登录设备方法
  13. JAVA博雅楼自习室预约系统计算机毕业设计Mybatis+系统+数据库+调试部署
  14. 分析 | 高通骁龙845已发布,明年智能手机会变成什么样
  15. SAP 发出商品业务配置
  16. 【华为机试真题Python】工厂流水线调度
  17. 张志华-统计机器学习-随机变量
  18. php网页爬虫-简单的类
  19. 强连接运营社张强:三分钟学会社群运营,从这三个方面、六个引流涨粉技巧出发
  20. pcie扰码的作用_CDMA中扰码的作用

热门文章

  1. 高手 清清月儿,收藏
  2. WEEK 8作业 A/D-区间选点 B-猫猫向前冲 C-班长竞选
  3. 微信拉黑的人怎么找回来?3个方法解决!
  4. 应用程序主题生成很简单!界面控件DevExtreme有现成的主题生成器
  5. 前端还能这么玩?(女朋友生日,用前端写了一个好玩的送给了她,高兴坏了)
  6. 天创速盈电商:拼多多运营技巧有哪些?注意事项有哪些?
  7. html编写代码的目录树
  8. 川大电子信息学院c语言复试,电子信息学院微机原理学姐经验分享给大家
  9. 基于Python多元线性回归模型
  10. 关于我用xhtmlrenderer将html转换img结果样式飞了的这档事