缓存
- plist(主要是系统设置)
- Cache缓存 (保存在磁盘、内存中)
NSCache
1.NSCache
简单介绍
1)NSCache是苹果官方提供的缓存类,具体使用和NSMutableDictionary类似,在AFN和SDWebImage框架中被是用来管理缓存
2)NSCache在系统内存很低时,会自动释放对象,接收到内存警告时主动调用removeAllobject方法释放对象
3)NSCache是线程安全的,在多线程操作中,不需要对NSCache加锁
2.NSCache
属性和方法介绍
1)属性介绍:
name:名称
delegat:设置代理
totalCostLimit:缓存控件的最大总成本,超出上限会自动回收对象,默认值为0,表示没有限制
countLimit:能够缓存的对象的最大数量:默认值为0,表示没有限制
evicrsObjectsWithDiscardedContent:标识缓存是否回收废弃的内容
2)方法介绍:
在缓存中设置指定键名对应的值,0成本
-(void)setObject:(ObjectType)obj forkey:(KeyType)key;
在缓存中设置指定键名对应的值,并且指定该键值对的成本,用于计算记录在缓存中的所有对象的总成本,当出现内存警告或者超出缓存总成本上限的时候,缓存会开启一个回收过程,删除部分元素
-(void) setObject:(ObjectType)obj forKey:(keyType)keycost:(NSUInteger)g;
删除缓存中指定键名的对象
-(void)removeObjcetForKey:(keyType)key;
删除缓存中所有的对象
-(void)removeAllObjects;
YYCache
1.简书汉斯哈哈哈
http://www.jianshu.com/p/b8dcf6634fab
2.YYCache 基于sqlite3.0
(1)SQLite轻量级的数据库 使用原生的C函数库 使用时添加libsqlite3.dylib 接着在使用SQLite API的Object-C类中使用 导入头文件 #import<sqlite3.h>
(2)数据存取读出:
** 存:存入内存时同时写入磁盘。
** 读:
1)先从内存中读,有就直接拿来用;
2)内存没有再从磁盘读,磁盘有就直接拿来用,并写入内存;
3)内存和磁盘都没有,返回空。
YYMemoryCache
http://www.jianshu.com/p/492c3c3a0485
实现原理
YYMemoryCache
是内存缓存,存取速度非常快。但缓存的容量是有限的,当Cache占满后,再缓存数据就失败,必须选择一个缓存快来替换掉已经缓存了的块。
1.LRU 应运而生
LRU 根据各块使用情况,总是选择那个最长时间未被使用的块替换。
LRU 缩写为Least Recently Used 即最近最少使用 它是一种页面置换算法同时也是一种缓存机制。
2.LRU采用两种数据结构实现
双向链表
哈希表
3.Cache操作
插入:当Cache未满时,新的数据项只需插入到双链表头部即可
查找:每次数据项被查询到,都将此数据项移动到链表头部
替换:当Cache满时,将新的数据项查到双链表头部,并删除双链表的尾结点。
使用
1.图标--最常用的图标显示
内存缓存的处理思路
1)当图片下载完成后,除了在TableView显示外,还要保存一份在内存缓存中
2)当图片需要展示的时候,先查看是否已经下载过,如果已经下载过,有缓存,如果有那么直接使用缓存里的数据,否则下载下来用
3)可以用字典和数组的方式实现
示例代码
- (NSMutableDictionary *)imageCache{
if (_imageCache ==nil) {
_imageCache = [NSMutableDictionary dictionary];
}
return _imageCache;
}
磁盘缓存的处理思路
1)当图片下载完成后,除了保存一份在内存缓存中,还要保存一份到沙盒中,也就是磁盘中
2)查看是否有磁盘缓存,如果有那么使用磁盘磁盘,保存一份到内存中
//1.得到cache路径
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
//2.文件名称
NSString *fileName = [appM.icon lastPathComponent];
//3.拼接文件的全路径
NSString *fullpath = [caches stringByAppendingPathComponent:fileName];
//4.尝试查看是否有磁盘缓存
NSData *data = [NSData dataWithContentsOfFile:fullpath];
//5.废弃磁盘缓存
data = nil;
if (data) {
UIImage *image = [UIImage imageWithData: data];
cell.imageView.image = image;
//6.保存一份到内存中
[self.images setObject:image forKey:appM.icon];
NSLog(@"%zd行 对应的图片 从 磁盘 中加载",indexPath.row);
2.当发生内存警告的时候 手动清理内存缓存
[self.image removeAllObject];
3.当下载图片可能会出现的问题
(1)UI卡顿 所有的下载都在主线程中处理,解决办法 开子线程下载图片
(2)图片重复下载(用户上下滚动) 内存缓存--->优化(磁盘缓存)
(3)当网速很慢的时候,图片的下载操作会被添加到队列中多次,当内存缓存和磁盘缓存中图片都不存在的时候,先检查图片的下载操作是否存在,如果存在那么等待即可,如果图片的下载操作不存在,那么再去封装操作去下载该图片-->操作缓存
(4)数据显示错乱
先清空cell的图片或者设置占位符
(5)url不正确等数据问题
下载完图片之后先判断图片是否有值,有就直接返回或者从操作缓存中删除