NSCache
NSCache 是苹果官方提供的缓存类,用法与 NSMutableDictionary 的用法很相似,在 AFNetworking 和 SDWebImage 中,使用它来管理缓存
NSCache 在系统内存很低时,会自动释放一些对象
备注:这句话源自苹果的官方文档,不过在模拟器中模拟内存警告时,缓存不会做清理动作 为了确保接收到内存警告时能够真正释放内存,最好调用一下 removeAllObjects 方法NSCache 是线程安全的,在多线程操作中,不需要对 Cache 加锁
NSCache 的 Key 只是做强引用,不需要实现 NSCopying 协议
属性
name delegate totalCostLimit缓存空间的最大总成本,超出上限会自动回收对象 默认值是 0,表示没有限制
countLimit
能够缓存对象的最大数量 默认值是 0,表示没有限制evictsObjectsWithDiscardedContent
标示缓存是否回收废弃的内容 默认值是 YES,表示自动回收方法
-objectForKey: 返回与键值关联的对象 -setObject:forKey:在缓存中设置指定键名对应的值 与可变字典不同,缓存对象不会对键名做 copy 操作 0 成本 -setObject:forKey:cost:
在缓存中设置指定键名对应的值,并且指定该键值对的成本 成本 (cost) 用于计算记录在缓冲中的所有对象的总成本
置对象并指定”成本”,成本可以自行指定
啥叫成本?
例子:缓存图片 缓存 100 张图片 将图片的”宽 * 高”当作成本,图像”像素” 10M 当作缓存成本,无论缓存的多少张照片,只要像素值超过 10M,就自动清理 缓存图像的时候,使用成本,比单纯设置数量要科学!(void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g;
当出现内存警告时,或者超出缓存的总成本上限时,缓存会开启一个回收过程,删除部分元素
-removeObjectForKey:
删除缓存中,指定键名的对象
-removeAllObjects
删除缓存中所有对象(很可怕,最好别用)委托方法
cache:willEvictObject缓存将要删除对象时调用 不能在此方法中修改缓存
代码演练
需要实现NSCacheDelegate
实现代理方法:
1
2
3
4
5
6
7
8
|
// MARK: NSCache Delegate
// 当缓存中的对象被清除的时候,会自动调用
// obj 就是要被清理的对象
// 提示:不建议平时开发时重写!仅供调试使用
- ( void )cache:(NSCache *)cache willEvictObject:(id)obj {
[NSThread sleepForTimeInterval: 0.5 ];
NSLog(@ "清除了-------> %@" , obj);
}</code>
|
声明NSCache变量:
1
|
@property (nonatomic, strong) NSCache *cache;
|
懒加载:
1
2
3
4
5
6
7
8
9
|
- (NSCache *)cache {
if (_cache == nil) {
_cache = [[NSCache alloc] init];
// 设置数量限制,最大限制为10
_cache.countLimit = 10 ;
_cache.delegate = self;
}
return _cache;
}
|
测试Demo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
- ( void )touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for ( int i = 0 ; i < 20 ; ++i) {
NSString *str = [NSString stringWithFormat:@ "hello - %04d" , i];
NSLog(@ "设置 %@" , str);
// 添加到缓存
[self.cache setObject:str forKey:@(i)];
}
// - 查看缓存内容,NSCache 没有提供遍历的方法,只支持用 key 来取值
for ( int i = 0 ; i < 20 ; ++i) {
NSLog(@ "缓存中----->%@" , [self.cache objectForKey:@(i)]);
}
}
|
运行结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
2015 - 03 - 25 09 : 27 : 19.953 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0000
2015 - 03 - 25 09 : 27 : 19.954 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0001
2015 - 03 - 25 09 : 27 : 19.954 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0002
2015 - 03 - 25 09 : 27 : 19.954 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0003
2015 - 03 - 25 09 : 27 : 19.954 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0004
2015 - 03 - 25 09 : 27 : 19.954 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0005
2015 - 03 - 25 09 : 27 : 19.954 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0006
2015 - 03 - 25 09 : 27 : 19.955 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0007
2015 - 03 - 25 09 : 27 : 19.955 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0008
2015 - 03 - 25 09 : 27 : 19.955 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0009
2015 - 03 - 25 09 : 27 : 19.955 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0010
2015 - 03 - 25 09 : 27 : 20.456 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0000
2015 - 03 - 25 09 : 27 : 20.457 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0011
2015 - 03 - 25 09 : 27 : 20.957 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0001
2015 - 03 - 25 09 : 27 : 20.957 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0012
2015 - 03 - 25 09 : 27 : 21.458 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0002
2015 - 03 - 25 09 : 27 : 21.459 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0013
2015 - 03 - 25 09 : 27 : 21.959 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0003
2015 - 03 - 25 09 : 27 : 21.959 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0014
2015 - 03 - 25 09 : 27 : 22.461 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0004
2015 - 03 - 25 09 : 27 : 22.461 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0015
2015 - 03 - 25 09 : 27 : 22.962 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0005
2015 - 03 - 25 09 : 27 : 22.962 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0016
2015 - 03 - 25 09 : 27 : 23.464 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0006
2015 - 03 - 25 09 : 27 : 23.464 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0017
2015 - 03 - 25 09 : 27 : 23.965 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0007
2015 - 03 - 25 09 : 27 : 23.965 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0018
2015 - 03 - 25 09 : 27 : 24.466 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0008
2015 - 03 - 25 09 : 27 : 24.466 01 -NSCache演练[ 26010 : 681046 ] 设置 hello - 0019
2015 - 03 - 25 09 : 27 : 24.967 01 -NSCache演练[ 26010 : 681046 ] 清除了-------> hello - 0009
2015 - 03 - 25 09 : 27 : 24.967 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.967 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.968 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.968 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.968 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.968 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.969 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.969 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.969 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.969 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->( null )
2015 - 03 - 25 09 : 27 : 24.969 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0010
2015 - 03 - 25 09 : 27 : 24.970 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0011
2015 - 03 - 25 09 : 27 : 24.970 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0012
2015 - 03 - 25 09 : 27 : 24.970 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0013
2015 - 03 - 25 09 : 27 : 24.970 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0014
2015 - 03 - 25 09 : 27 : 24.971 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0015
2015 - 03 - 25 09 : 27 : 24.971 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0016
2015 - 03 - 25 09 : 27 : 24.971 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0017
2015 - 03 - 25 09 : 27 : 24.971 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0018
2015 - 03 - 25 09 : 27 : 24.971 01 -NSCache演练[ 26010 : 681046 ] 缓存中----->hello - 0019
|
总结
通过打印结果可以知道,当超多最大成本限制的时候,会先清除缓存中的一条数据,再存入一条新的数据。最后缓存中只能保存最大成本数的数据,即10条。