YYCache基本介绍
YYCache内部包括YYMemeryCache、YYDiskCache。其基本使用比较简单,例如初始化方法initWithName(提供默认路径),initWithPath(自定义路径),类方法cacheWithName,cacheWithPath。添加key-value时会同时向YYMemeryCache、YYDiskCache添加,检索只要其中任意一个查找到key-value则返回。YYCache可以设置内存和硬盘各自存储的限制。这个类提供了使用YYMemeryCache、YYDiskCache的便捷入口。业务要求简单的话可以直接使用即可。
YYMemeryCache
其他内存缓存:
NSCache 是苹果提供的一个简单的内存缓存,它有着和 NSDictionary 类似的 API,不同点是它是线程安全的,并且不会 retain key。我在测试时发现了它的几个特点:NSCache 底层并没有用 NSDictionary 等已有的类,而是直接调用了 libcache.dylib,其中线程安全是由 pthread_mutex 完成的。另外,它的性能和 key 的相似度有关,如果有大量相似的 key (比如 “1”, “2”, “3”, …),NSCache 的存取性能会下降得非常厉害,大量的时间被消耗在 CFStringEqual() 上,不知这是不是 NSCache 本身设计的缺陷。
关键代码及思路梳理:
init中配置互斥锁_lock: 对内部链表_lru进行操作(查询count、trim等)时加锁
线程_queue:在该线程中异步trim。
递归trim:默认5S trim一次
初始化_lru:_YYLinkepMap中_dic负责key-value数据存储,链表基本信息及链表移动、加入、移除等操作;其中key为用户原始key,value为_YYLinkedMapNode。
setObjectForKey:
使用CFDictionaryGetValue通过key查找是否存在node,查找目标_lru->dic。如果查找到了则修改node的value,并移动到链表最前面,没有则创建节点,放置链表最前面。完成后根据limit进行trim。
objectForKey:
在_lru->dic通过key查找到node后,更新node的time,移动到链表头,返回node->value;
调用setObjectForkey及ObjectForkey都更新了node的time,并移动到链表头,在使用trimToCount,trimToAge时都可以进行循环依次移除从尾节点
从_lru->dic中移除node后,将node 放入holderarray,根据_releaseOnMainThread,找到对应queue进行node的异步释放(释放掉holdArray)。
其他总结:
类的接口暴露:提供默认方式及类方法。
一些可配置项,例如最大数量等,使用宏定义在初始化时进行默认配置,暴露可配置属性。
链表的基本操作
带源代码及更细介绍参见另一位博主http://www.jianshu.com/p/78ad114219a6