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来去查找过期文件的

查找过期文件是通过缓存存取时间是否小于ageLimit来判断的。那么如果我们设置硬盘缓存10分钟过期,就应该是 diskCache.ageLimit = time(NULL) + 60*10;
但是看下面的代码,我们发现,移除的时间参数,使用的是 当前时间戳与ageLimit的差值。

因此,对于硬盘缓存来说,不管怎么设置ageLimit,都是有问题的。
解决方案应该是将ageLimit这个参数传递给removeItemsEarlierThanTime:方法。如下图:

网友评论