设计思路

利用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的设计思路链接

YYCache设计思路及源码学习的更多相关文章

  1. asp.net abp模块化开发之通用树2:设计思路及源码解析

    一.前言 上一篇大概说了下abp通用树形模块如何使用,本篇主要分析下设计思路. 日常开发中会用到很多树状结构的数据,比如:产品的多级分类.省市区县,大多数系统也会用到类似“通用字典/数据字典”的功能, ...

  2. CopyOnWriteArrayList设计思路与源码分析

    CopyOnWriteArrayList实现了List接口,RandomAccess,Cloneable,Serializable接口. CopyOnWriteArrayList特性 1.线程安全,在 ...

  3. 【 js 基础 】【 源码学习 】源码设计 (持续更新)

    学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析第二部分:undersc ...

  4. 【 js 基础 】【 源码学习 】源码设计 (更新了backbone分析)

    学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析 第二部分:unders ...

  5. Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构(源码可下载)

    Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构(源码可下载) 说明:Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构,我采用以下三种维度来讲解 1.  代码层面. 2.  数 ...

  6. Vue2.1.7源码学习

    原本文章的名字叫做<源码解析>,不过后来想想,还是用“源码学习”来的合适一点,在没有彻底掌握源码中的每一个字母之前,“解析”就有点标题党了.建议在看这篇文章之前,最好打开2.1.7的源码对 ...

  7. JDK源码学习笔记——Integer

    一.类定义 public final class Integer extends Number implements Comparable<Integer> 二.属性 private fi ...

  8. Vue.js 源码学习笔记

    最近饶有兴致的又把最新版 Vue.js 的源码学习了一下,觉得真心不错,个人觉得 Vue.js 的代码非常之优雅而且精辟,作者本身可能无 (bu) 意 (xie) 提及这些.那么,就让我来吧:) 程序 ...

  9. spring源码学习之AOP(一)

    继续源码学习,看了spring中基础的容器和AOP感觉自己也没有什么长进,哈哈,我也不知道到底有用没有,这可能是培养自己的一种精神吧,不管那么多,继续学习!AOP中 AOP中几个重要的概念:(1)Ad ...

随机推荐

  1. Android下OpenCV的环境搭建

    目录(?)[-] 前言 系统环境 相关工具 Android ADT环境搭建 Android SDK环境变量的配置 Android NDK的安装与配置 OpenCV for Android 环境搭建 基 ...

  2. Eclipse的安装与调试

    1.首先进入eclipse官网下载eclipse 2.根据自己的系统选择相应版本进行下载.由于我的是64bit,所以我选择64bit版下载. 3.点开下载的程序,进行安装. 4.随后进入了安装页面.和 ...

  3. 网络适配器输入的IP地址 已经分配给另一个适配器

    解决步骤:1.开始-运行-cmd2. set devmgr_show_nonpresent_devices=123.set devmgr_show_nonpresent_devices=14.star ...

  4. xhtml 和 html 的区别

    xhtml遵循xml文档规则,对于书写比较严格,相对于html来说,主要有以下不同: 标签不能重叠,可以嵌套标签与属性都要小写标签都要有始有终,要么以</p>形式结束,要么以<br ...

  5. Java找不到或无法加载主类

    今天用cmd运行一下java出现了找不到或无法加载主类 的问题 javac编译可以通过   java运行不了 原因: 看一下java版本 看一下javac版本: 编译和运行环境的版本不一样报错原来是用 ...

  6. PHPExcel--基本操作

    下面是PHPExcel的导入与导出的基本操作,也是最重要的两个操作. 生成文件: <?php require_once './Classes/PHPExcel.php'; $content = ...

  7. MySQL的create table as 与 like区别

    对于MySQL的复制相同表结构方法,有create table as 和create table like 两种,区别是什么呢? ? 1 create table t2 as select * fro ...

  8. Unable to execute dex: GC overhead limit exceeded

    Android打包时下面的错误: Unable to execute dex: GC overhead limit exceeded GC overhead limit exceeded 解决的方法: ...

  9. [转] 将DOS格式文本文件转换成UNIX格式

    点击此处阅读原文 用途说明 dos2unix命令用来将DOS格式的文本文件转换成UNIX格式的(DOS/MAC to UNIX text file format converter).DOS下的文本文 ...

  10. [转] How to debug a ARM Cortex-M hard fault exception

    how to debug a ARM Cortex-M hard fault exception