简介

1)NSCache 是苹果官方提供的缓存类,用法与 NSMutableDictionary 的用法很相似,在 AFNetworking 和 SDWebImage 中,使用它来管理缓存。

2)NSCache 在系统内存很低时,会自动释放一些对象(备注:在模拟器中内存警告时,缓存不会做清理动作)。开发中为了确保收到内存警告时真正释放内存,最好调用 - (void)removeAllObjects; 方法。

3)NSCache 是线程安全的,在多线程操作中,不需要对 NSCache 加锁。

4)NSCache 的 key 只是做强引用,不需要实现 NSCopying协议

属性:

/** 名称 */
@property (copy) NSString *name;
/** 代理 */
@property (nullable, assign) id<NSCacheDelegate> delegate;
/** 缓存空间的最大总成本,超出上限会自动回收对象,默认值是 0,表示没有限制 */
@property NSUInteger totalCostLimit;
/** 能够缓存对象的最大数量,默认值是 0,表示没有限制 */
@property NSUInteger countLimit;
/** 标识缓存是否回收废弃的内容,默认值是 YES,表示自动回收 */
@property BOOL evictsObjectsWithDiscardedContent;

方法:

/**
返回与键值关联的对象
*/
- (nullable ObjectType)objectForKey:(KeyType)key; /**
在缓存中设置指定键名对应的值,与可变字典不同,缓存对象不会对键名做 copy 操作,0 成本
*/
- (void)setObject:(ObjectType)obj forKey:(KeyType)key; /**
在缓存中设置指定键名对应的值,并且指定该键值对的成本。当出现内存警告时,或者超出缓存的总成本上限时,缓存会开启一个回收过程,删除部分元素
@param cost 成本 (cost) 用于计算记录在缓冲中的所有对象的总成本
*/
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g; /**
删除缓存中,指定键名的对象
*/
- (void)removeObjectForKey:(KeyType)key; /**
删除缓存中所有对象
*/
- (void)removeAllObjects;

委托方法:

/**
缓存将要删除对象时调用,注意:不能在此方法中修改缓存!!
*/
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;

简单实例:

/**

* 在此提供一个例子来进行缓存使用的说明

* 需求:将字符串存入缓存,并进行查看和清理。

* 准备:在Main.storyboard中添加按钮,分别为添加、检查和删除缓存。(在此使用需要成本的方式进行测试)

*/ 

1、创建缓存对象

/** 缓存属性 */
@property (nonatomic, strong) NSCache *cache;
// 通过懒加载的方式创建缓存对象
- (NSCache *)cache{
if (!_cache) {
_cache = [[NSCache alloc] init];
// 设置成本为5 当存储的数据超过总成本数,NSCache会自动回收对象
_cache.totalCostLimit = ;
// 设置代理 代理方法一般不会用到,一般是进行测试的时候使用
_cache.delegate = self;
}
return _cache;
}

2、实现按钮的点击方法

// 添加缓存
- (IBAction)addCache {
for (int i = ; i < ; i++) {
NSString *str = [NSString stringWithFormat:@"在这里进行了存储数据"];
// 设置成本数为1
[self.cache setObject:str forKey:@(i) cost:];
NSLog(@"存储数据----%@",@(i));
}
}
// 检查缓存
- (IBAction)checkCache {
NSLog(@"---------------------------------------------");
for (int i = ; i < ; i++) {
NSString *str = [self.cache objectForKey:@(i)];
if (str) {
NSLog(@"取出缓存中存储的数据-----%@",@(i));
}
}
}
// 清理缓存
- (IBAction)deleteCache {
[self.cache removeAllObjects];
NSLog(@"清理缓存");
}

3、实现代理

#pragma mark - NSCacheDelegate
// 即将回收对象的时候进行调用,实现代理方法之前要遵守NSCacheDelegate协议。
- (void)cache:(NSCache *)cache willEvictObject:(id)obj{
NSLog(@"回收--------%@",obj);
}

4、打印说明

4.1 点击添加按钮的打印

存储数据----

存储数据----

存储数据----

存储数据----

存储数据----

回收--------在这里进行了存储数据

存储数据----

回收--------在这里进行了存储数据

 存储数据----

 回收--------在这里进行了存储数据

 存储数据----

回收--------在这里进行了存储数据

存储数据----

回收--------在这里进行了存储数据

存储数据----

4.2 点击检查按钮的打印

 ---------------------------------------------

取出缓存中存储的数据-----

 取出缓存中存储的数据-----

取出缓存中存储的数据-----

 取出缓存中存储的数据-----

取出缓存中存储的数据-----

4.3 打印相关的解释

在此因为进行每个字符串对象存储时,成本是1,我们设置的总成本是5,字符串对象存储了10次,总成本是10,所以在存储数据5的时候会回收数据1的字符串对象,以此类推,所以打印的结果如上所示。关于清理缓存和其他相关的操作由读者们自行打印,在此不做赘述了。

补充:

/**

*  如果把例子中的添加缓存写成如下方式,就不会存在回收的打印,在检查缓存的时候也会有10条数据。

*  解释:NSCache的Key只是对对象进行了Strong引用,而非拷贝。

*  当写在for循环外部时,所以对于字符串对象只是在内存中建立了10个强引用,而存储的真正的字符串对象只有一个(字符串对象只创建了一次),所以总成本为1。

*  当写在for循环内部时,字符串对象只是在内存中建立了10个强引用,而存储的真正的字符串对象有十个(每次都在创建新的字符串对象),所以总成本为10。

*/

// 添加缓存
- (IBAction)addCache {
// NSCache的Key只是对对象进行了Strong引用,而非拷贝,
NSString *str = [NSString stringWithFormat:@"在这里进行了存储数据"];
for (int i = ; i < ; i++) {
// 设置成本数为1
[self.cache setObject:str forKey:@(i) cost:];
NSLog(@"存储数据----%@",@(i));
}

NSCache的简单使用的更多相关文章

  1. NSCache类的简单介绍

    最近看SDWebImage,里面的内存缓存用到了NSCache这个类,由于以前没有使用过,特此记录学习一下. NSCache NSCache是苹果官方提供的缓存类,用法和NSMutableDicton ...

  2. iOS开发——多线程篇——快速生成沙盒目录的路径,多图片下载的原理、SDWebImage框架的简单介绍

    一.快速生成沙盒目录的路径 沙盒目录的各个文件夹功能 - Documents - 需要保存由"应用程序本身"产生的文件或者数据,例如:游戏进度.涂鸦软件的绘图 - 目录中的文件会被 ...

  3. NSURLCache 和 NSCache 的区别

    NSURLCache 和 NSCache 的区别 NSURLCache提供的是URL Request缓存,可以在Memory和Disk上:NSCache提供了HTTP Request外的东西的缓存方式 ...

  4. 多线程与网络之SDWebImage和NSCache

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  5. iOS NSCache缓存类的了解

    前言:   最近面试时,问到了限定并发数的视频下载,当时回答的时通过GCD_barrier 处理,回来想想也可以通过NSCache处理,所以顺便复习一下,这个知识点. 一,关于NSCache说明 说明 ...

  6. 【造轮子】打造一个简单的万能Excel读写工具

    大家工作或者平时是不是经常遇到要读写一些简单格式的Excel? shit!~很蛋疼,因为之前吹牛,就搞了个这东西,还算是挺实用,和大家分享下. 厌烦了每次搞简单类型的Excel读写?不怕~来,喜欢流式 ...

  7. Fabio 安装和简单使用

    Fabio(Go 语言):https://github.com/eBay/fabio Fabio 是一个快速.现代.zero-conf 负载均衡 HTTP(S) 路由器,用于部署 Consul 管理的 ...

  8. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  9. 哪种缓存效果高?开源一个简单的缓存组件j2cache

    背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...

随机推荐

  1. windows 自动贴边

    设置windows 自动贴边(窗口拖到显示器边框就自动适应屏幕): https://jingyan.baidu.com/article/d2b1d1029d17b95c7e37d4f0.html 资源 ...

  2. Business talking in English

    Talking one: A: Microsoft, this is Steve. B: Hi Steve, this is Richard from Third Hand Testing. I am ...

  3. JMeter乱码常见的解决方案

    方法一.直接将JMeter中http请求中Content encoding改为utf-8 方法二.编辑JMeter安装目录:apache-jmeter-3.2\bin中的jmeter.properti ...

  4. httpd的一些知识点

    一.httpd持久化连接:使用httpd之telnet测试其keepalive连接状态 作用:连接建立后,每个资源获取结束不会断开连接,而继续等待其他资源请求并完成传输. 1.KeepAlive  O ...

  5. 6.2Python文件的操作(二)

    目录 目录 前言 (一)文件的定位 (二)文件的读操作 ==1.read()方法== ==2.readline()方法== ==3.readlines()方法== ==4.文件的遍历读法== (三)文 ...

  6. linux系统日志自动切割工具----logrotate

    参考资料 :https://www.cnblogs.com/kevingrace/p/6307298.html 对于Linux系统安全来说,日志文件是极其重要的工具.不知为何,我发现很多运维同学的服务 ...

  7. Linux 小知识翻译 - 「i386」是什么?

    i386是指 *CPU* 的种类,也可以指 *CPU* 的架构(architecture). 现在的 CPU 一般都用 「Core 2 Duo」或者「Athlon」,「Xeon」,「Opteron」之 ...

  8. Windows安装PostgreSQL11.1

    Windows安装PostgreSQL11.1 安装过程如下: 1.下载安装包postgresql-11.1-1-windows-x64.exe 2.点击下一步 3.选择安装位置,默认路径C:\Pro ...

  9. Spring集成MyBatis持久层框架

    一.MyBatis介绍 MyBatis 是一款优秀的持久层框架,它支持定制化SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,可以使用简单的XML ...

  10. swift的调用约定

    swift的静态绑定 Swift Calling Convention @convention(swift) func foo(_ x:Int, y:Int) sil @foo : $(x:Int, ...