关于YYCache的缓存过期时间的设置问题

YYCache有多优秀,我就不多介绍了,关于它源码的分析网上一搜一大堆。

今天来聊一下YYCache里的ageLimit.因为我已经被这个属性坑了两次……

缓存超时时间设置,分为设置内存缓存超时时间和硬盘缓存超时时间

内存缓存过期时间

原理是:memoryCache初始化的时候,就开启了一个循环调用,每隔一段时间去检查缓存是否过期,是否超过限制等。
关于ageLimit。开始调用_trimToAge的时候,从链表尾部开始比较,如果过期就删掉,然后继续进行比较……。

这里要注意的是超时时间ageLimit的属性设置。因为源码内部,每次更新操作后,存的_now对应的时间是CACurrentMediaTime(),代码内部判断过期不过期是通过: 当前时间(CACurrentMediaTime()计算得到)- 链表元素记录的时间差值 与 ageLimit进行比较。那么我们设置10分钟缓存,应该这样设置: diskCache.ageLimit = 600;

硬盘缓存过期时间

原理和内存缓存是一样的。区别是每个硬盘缓存对象YYDiskCache,它是由单例持有的,不需要我们去担心对象是否被销毁。不用每次都去创建yydiskcache对象。yydiskCache对象初始化的时候开启循环调用,每隔一段时间去检查缓存,如果缓存时间超过了ageLimit,就要去清除掉。

但是经过翻看源码,发现ageLimit这个属性的使用代码存在问题。

硬盘缓存,每次更新操作过数据后,表内的last_access_time字段存的是通过time(NULL)获取的当前时间戳。

removeItemsEarlierThanTime: 方法内部,是通过下面的sql来去查找过期文件的

关于YYCache的缓存过期时间的设置问题_第1张图片
444.png

查找过期文件是通过缓存存取时间是否小于ageLimit来判断的。那么如果我们设置硬盘缓存10分钟过期,就应该是 diskCache.ageLimit = time(NULL) + 60*10;

但是看下面的代码,我们发现,移除的时间参数,使用的是 当前时间戳与ageLimit的差值。

关于YYCache的缓存过期时间的设置问题_第2张图片
555.png

因此,对于硬盘缓存来说,不管怎么设置ageLimit,都是有问题的。

解决方案应该是将ageLimit这个参数传递给removeItemsEarlierThanTime:方法。如下图:

关于YYCache的缓存过期时间的设置问题_第3张图片
666.png

写在最后

个人不建议对内存缓存设置这个ageLimit。因为每次获取数据的时候,都会更新缓存的时间。比如你刚刚存了一个对象,设置了10分钟缓存时效,当你第9分钟的时候去获取使用了该缓存,这个缓存就立马被更新了,要到下个10分钟后才会过期。如果要控制一个缓存的时间,最好自己单独实现。

你可能感兴趣的:(关于YYCache的缓存过期时间的设置问题)