AFAutoPurgingImageCache_YYCache_SDImageCache

缓存


5大方法:增加,获取,删除指定,删除全部,是否存在(contains OR exists),用cnt,size和age来限制。

自定义缓存

<1> 选择一个合适的缓存键 - 缓存键用来做图片的唯一标识。如果实时创建图片,通常不太好生成一个字符串来区分别的图片。我们可以用图片的文件名或者表格索引

<2> 提前缓存 - 如果生成和加载数据的代价很大,你可能想当第一次需要用到的时候再去加载和缓存。提前加载的逻辑是应用内在就有的,对于一个给定的位置和滚动方向,我们就可以精确地判断出哪一张图片将会出现。

<3> 缓存失效(时间戳)- 如果图片文件发生了变化,怎样才能通知到缓存更新呢?这是个非常困难的问题,但是幸运的是当从程序资源加载静态图片的时候并不需要考虑这些。对用户提供的图片来说(可能会被修改或者覆盖),一个比较好的方式就是当图片缓存的时候打上一个时间戳以便当文件更新的时候作比较。

<4> 缓存回收 - 当内存不够的时候,如何判断哪些缓存需要清空呢?这就需要到你写一个合适的算法了。对缓存回收的问题,苹果提供了一个叫做NSCache通用的解决方案




AFAutoPurgingImageCache实际是NSDcit+变量控制的缓存(当接收到内存警告通知 -> removeAllImages)

(容量 - 当前内存用量 - identifier - lastAccessDate)

<1> 封装一个AFCachedImage对象,用cachedImages字典来存储。

<2> 主要方法:

-addImage:withID - 覆盖之前ID的cachedImage。如果超出容量,则清除最早访问时间的图片。removeID/All,Get。

-addImage:forRequest中用request.URL.absoluteString+additionalID做图片的ID。




YYCache

`YYCache`是一个线程安全的KV缓存

`YYMemoryCache`存储对象在一个小而快的内存缓存

`YYDiskCache`持久化对象在一个大而慢的磁盘缓存

对YYMemoryCache 和 YYDiskCache的简单方法封装。


YYMemoryCache

API和性能与`NSCache`类似,与其不同:

<1> 使用LRU移除对象,NSCache的移除方法是非确定的

<2> 能够控制cost,count和age。NSCache的限制不准确

<3> 当获得内存警告或者app进入后台(默认,removeAll),能自动配置移除对象。


_YYLinkedMap  -  _YYLinkedMapNode

LRU 是用双向链表(保持尾部时间最久)配合 NSDictionary 实现的,增、删、改、查、清空的时间复杂度都是 O(1)

把node的key和value存入LinkedMap内部的CF字典(_totalCost+_totalCnt)中,实现O(1)的数据访问。双向链表采用头插法,每次获取node,会更新_time,并bringNodeToHead。同时,如果setObj时,如果node结点存在,也会bringNodeToHead

5s递归循环的后台Low优先级队列。5s后异步串行的执行_trimCost(循环去尾,放入holderArr,异步后台队列释放内存)/Count同/Age同。


YYKVStorage

一般,写数据到sqlite比到外部文件要快,但是读数据的性能取决于数据的大小。测试中,当数据超过20KB时,从外部文件读数据要比sqlite快。

<1> 如果要存储大量小数据(如联系人缓存),用YYKVStorageTypeSQLite来获得更好的性能

<2> 如果要存储大文件(如图片缓存),用YYKVStorageTypeFile获得更好的性能

<3> 用YYKVStorageTypeMixed,为每个item选择你的存储类型

初始化后,基于`path`创建一个目录来持有key-value data。打开db,建表。


_dbStmtCache缓存(key - sqlString,value - sqlite3_stmt)

<1> 直接操作sqlite3的CRUD。

<2> file的CRUD


YYDiskCache

线程安全的缓存,存储键值对,通过SQLite和文件系统(类似NSURLCache的磁盘缓存)

* LRU删除对象

* 控制cost, count, and age

* 当没有空闲磁盘空间,通过配置自动删除对象

* 为所有对象自动决定存储类型(sqlite/file)以获得更好的性能


<1> 维护一个全局的mapTable缓存(key - cache.path,value - cache)

60s递归循环的后台Low优先级队列。60s后异步并发的执行_trimCost(_kv方法)/Count同/Age同/FreeDiskSpace(调用_trimCost)。

<2> 初始化设置时,有一个InlineThreshold,0表示所有对象都将以单独的文件存储,NSUIntegerMax表示所有的对象都存储于sqlite。

<3> 

objectForKey - 从数据库获取YYKVStorageItem对象,将item.value解档为id对象,有extendedData会设置为id对象的关联对象。

setObject:forKey - 尝试获取extendedData,将id对象归档为NSData,当_type不为SQlite且data长度>InlineThreshold,就通过key生成filename。最后调用_kv方法

这里,通过key生成filename,如果有自定义filenameBlock就调用,没有就对String编码后进行MD5。

其余都是加锁调用_kv方法。




SDImageCache

SDImageCache维护一个内存cache和一个可选的磁盘缓存。磁盘缓存写操作被异步执行,因此它不会延迟UI。


<1> 内存缓存使用AutoPurgeCache,AutoPurgeCache继承NSCache,监听内存警告通知,触发removeAll方法。

ImageDataHasPNGPreffix提供了检测PNG图片的方法(PNG头8个字节唯一)

对于由key获取filename,同样提供了MD5的方法cachedFilenameForKey

<2> 

监听DidReceiveMemoryWarning通知 = 调用removeAll清空内存缓存。WillTerminate通知 = cleanDisk。DidEnterBackground通知 = 后台任务过期Block 。cleanDisk,回调结束任务Block。

storeImage:recalculateFromImage:imageData:forKey:toDisk - 内存缓存 + 异步串行磁盘缓存 = 判断PNG或JPEG保存为data,存储data(diskCache+MD5的keyString)。

内存缓存图片从NSCache直接获取。磁盘缓存图片,首先从默认和自定义路径搜索,获取data,根据data创建image并按scale调整,最后提前解码并返回。

clearDisk - removeItem+新建目录。

cleanDisk - 异步串行队列 - 首先移除一周前的缓存文件, 然后若还超过MaxCacheSize,则清除oldest文件,直到size小于max的一半。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容