设计思路

利用YYCache来进行操作,实质操作分为了内存缓存操作(YYMemoryCache)和硬盘缓存操作(YYDiskCache)。内存缓存设计一般是在内存中开辟一个空间用以保存请求的数据(一般使用字典操作)。硬盘缓存设计即是将文件保存至本地,这种保存分为小文件保存和大文件保存,对于小文件保存使用数据库操作性能效率相对较高,对于大文件则使用直接存放。YYDiskCache为线程安全的类,其操作是基于YYKVStorage(线程不安全的类)的操作。以下为大致源码分析

主类YYCache

必须初始化名字 名字即为存储路径,NS_DESIGNATED_INITIALIZER提示为设计初始化方法,UNAVAILABLE_ATTRIBUTE定义为未实现方法,关于这两种宏定义都存在于系统框架中

- (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;

最终构造函数如下所示:包含了硬盘缓存和内存缓存

- (instancetype)initWithPath:(NSString *)path {
if (path.length == 0) return nil;
YYDiskCache *diskCache = [[YYDiskCache alloc] initWithPath:path];
if (!diskCache) return nil;
NSString *name = [path lastPathComponent];
YYMemoryCache *memoryCache = [YYMemoryCache new];
memoryCache.name = name;
self = [super init];
_name = name;
_diskCache = diskCache;
_memoryCache = memoryCache;
return self;
}

对于YYCache所设计方法,所做操作本质上来说就是增删改查,内部本质是对YYDiskCache和YYMemoryCache的操作,由于读取效率的问题,读取时先有内存缓存中读取,若没有则由硬盘缓存中读取(再存入内存缓存中)

- (BOOL)containsObjectForKey:(NSString *)key
- (void)containsObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key, BOOL contains))block
- (id<NSCoding>)objectForKey:(NSString *)key
- (void)objectForKey:(NSString *)key withBlock:(void(^)(NSString *key, id<NSCoding> object))block
- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key
- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key withBlock:(void(^)(void))block
- (void)removeObjectForKey:(NSString *)key
- (void)removeObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key))block
- (void)removeAllObjects
- (void)removeAllObjectsWithBlock:(void(^)(void))block
- (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress
endBlock:(void(^)(BOOL error))end

YYMemoryCache和YYDiskCache

为了方便理解和YYCache对YYDiskCache和YYMemoryCache的操作,两类的通用接口设计如下

- (BOOL)containsObjectForKey:(id)key
- (id)objectForKey:(id)key
- (void)setObject:(id)object forKey:(id)key
- (void)setObject:(id)object forKey:(id)key withCost:(NSUInteger)cost
- (void)removeObjectForKey:(id)key
- (void)removeAllObjects

在YYDiskCache则包含了YYCache中所有的接口设计

YYMemoryCache

主要成员变量

  1. pthread_mutex_t(保证线程安全)

  2. _YYLinkedMap自定义类(主包含数据映射字典和链表(根据LRU算法计算自动移除的节点))

  3. dispatch_queue_t操作队列(保证线程不阻塞)

    其中YYLinkeedMap包含了如下成员变量--LRU算法:常使用节点被移动到头结点,即经常使用的节点靠前越靠后就为越不常使用的节点具体实现可查看类中的insertNodeAtHead和bringNodeToHead方法

    CFMutableDictionaryRef _dic; // 字典内 存放对应的缓存数据

    NSUInteger _totalCost;

    NSUInteger _totalCount;

    _YYLinkedMapNode *_head; // 头结点

    _YYLinkedMapNode *_tail; // 尾节点,利用LRU算法实现

    BOOL _releaseOnMainThread;

    BOOL _releaseAsynchronously;

YYDiskCache

主要成员变量

  1. YYKVStorage *_kv; //硬盘存储主要类(线程不安全)
  2. dispatch_semaphore_t _lock;
  3. dispatch_queue_t _queue;

    在YYDiskCache中所做的操作都是基于YYKVStorage的操作,只是增加了信号量上锁以保证线程安全

YYKVStorage

此类主要是利用sqlite3和数据库打交道,当然对于比较大型的文件是直接使用系统的write方法来进行文件保存,这样能更大限度的提升效率。在YYKVStorage的存储中都是以对象的方式进行存储,其对象封装为YYKVStorageItem其中的字段设计如下

key                 text,
filename text,
size integer,
inline_data blob,
modification_time integer,
last_access_time integer,
extended_data blob,
primary key(key)

剩下的就是YYKVStorage如何利用sqlite3进行数据的访问,关于sqlite3的操作就不详述了。

以上便是整个YYCache设计的主要思路,当然里面包含了其他的一些东西。以笔者目前的功力还不能吃透,其中便是YYDispatchQueuePool,在这里YYCache中利用了自己设计的队列池来进行管理。由于没有这方面的经验和时间来学习。这一块就算留作以后研究的一个点吧。

最后贴上YY大神关于自己YYCache的设计思路链接

最新文章

  1. 使用python的redis 实现消息的pub/sub功能
  2. WebService的两种方式SOAP和REST比较 (转)
  3. PHP isset 函数作用
  4. Webpack使用教程六(Plugins)
  5. 通过JSTL+EL实现循环迭代
  6. HDU4268 Alice and Bob(贪心+multiset)
  7. An Data-Scientist Prepares 《数据科学家的自我修养》
  8. http://www.iteye.com/job/topic/1133159
  9. 四:java调接口实现发送手机短信验证码功能
  10. ACM中的fread读入
  11. Leetcode#1.Two Sum(两数之和)
  12. 力扣(LeetCode)463. 岛屿的周长
  13. SpringMVC redirect中文乱码问题
  14. hdu2594 Simpsons’ Hidden Talents LCS--扩展KMP
  15. Unity 之 transform
  16. Eclipse js报错问题解决办法
  17. js面向对象设计之class继承
  18. Apache HttpComponents 获取inputStream
  19. Oracle执行计划的查看
  20. linux下的which

热门文章

  1. Android 开发基础及环境配置
  2. 用于svn添加当前目录下所有未追踪的文件,和删除所有手动删除的文件的脚本
  3. Hadoop:操作 Hadoop Cluster
  4. 利用 Serial Over Lan(SOL)搭建 XEN 的调试信息输出环境
  5. Steve Loughran:Why not raid 0,its about time and snowflakes!!!
  6. Selenium 2.0 + Java 入门之环境搭建
  7. php常用函数(持续中)
  8. event.keyCode ,event.which ,event.charCode (2016-12-27 16:17:16)
  9. ES搜索引擎-简单入门
  10. 【转】如何配置android的adb环境变量