NSCache
-
NSCache是系统提供的一种类似于集合(NSMutableDictionary)的缓存,它与集合的不同如下:
-
- NSCache具有自动删除的功能,以减少系统占用的内存;
-
- NSCache是线程安全的,不需要加线程锁;
-
- 键对象不会像 NSMutableDictionary 中那样被复制。(键不需要实现 NSCopying 协议)。
-
-
NSCache的属性以及方法介绍:
-
@property NSUInteger totalCostLimit;
- 设置缓存占用的内存大小,并不是一个严格的限制,当总数超过了totalCostLimit设定的值,系统会清除一部分缓存,直至总消耗低于totalCostLimit的值。
-
@property NSUInteger countLimit;
- 设置缓存对象的大小,这也不是一个严格的限制。
-
-
-
(id)objectForKey:(id)key;
- 获取缓存对象,基于key-value对
-
-
-
(void)setObject:(id)obj forKey:(id)key; // 0 cost
- 存储缓存对象,考虑缓存的限制属性;
-
-
-
(void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g;
- 存储缓存对象,cost是提前知道该缓存对象占用的字节数,也会考虑缓存的限制属性,建议直接使用 – (void)setObject:(id)obj forKey:(id)key;
-
-
NSCacheDelegate代理
代理属性声明如下:
-
@property (assign) iddelegate;
- 实现了NSCacheDelegate代理的对象,在缓存对象即将被清理的时候,系统回调代理方法如下:
-
-
(void)cache:(NSCache *)cache willEvictObject:(id)obj;
-
第一个参数是当前缓存(NSCache),不要修改该对象;
-
第二个参数是当前将要被清理的对象,如果需要存储该对象,可以在此操作(存入Sqlite or CoreData);
-
-
-
该代理方法的调用会在缓存对象即将被清理的时候调用,如下场景会调用:
-
-
- (void)removeObjectForKey:(id)key; 手动删除对象;
-
-
- 缓存对象超过了NSCache的属性限制;(countLimit 和 totalCostLimit )
-
- App进入后台会调用;
-
- 系统发出内存警告;
-
-
练习
#import "ViewController.h"
@interface ViewController ()<NSCacheDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSCache *cache = [[NSCache alloc]init];
cache.name = @"testCache";
[cache setCountLimit:5];
cache.delegate = self;
NSString *test = @"Hello NSCache";
[cache setObject:test forKey:@"Test"];
NSLog(@"objectForKey:%@",[cache objectForKey:@"Test"]);
NSLog(@"name:%@",cache.name);
for (int i = 0; i < 10; i++)
{
[cache setObject:[NSString stringWithFormat:@"WorldCost%d", i] forKey:[NSString stringWithFormat:@"HelloCost%d", i] cost:1];
NSLog(@"Add key:%@ value:%@ to Cache", [NSString stringWithFormat:@"HelloCost%d", i], [NSString stringWithFormat:@"WorldCost%d", i]);
}
// for (int i = 0; i < 10; i++)
// {
// [cache setObject:[NSString stringWithFormat:@"World%d", i] forKey:[NSString stringWithFormat:@"Hello%d", i]];
// NSLog(@"Add key:%@ value:%@ to Cache", [NSString stringWithFormat:@"Hello%d", i], [NSString stringWithFormat:@"World%d", i]);
// }
// for (int i = 0; i < 10; i++)
// {
// NSLog(@"Get value:%@ for key :%@", [cache objectForKey:[NSString stringWithFormat:@"Hello%d", i]], [NSString stringWithFormat:@"Hello%d", i]);
// }
//// [cache removeAllObjects];
// for (int i = 0; i < 10; i++)
// {
// NSLog(@"Get value:%@ for key:%@", [cache objectForKey:[NSString stringWithFormat:@"World%d", i]], [NSString stringWithFormat:@"World%d", i]);
// }
// NSLog(@"Test %@", test);
//
}
// 当缓存中的一个对象即将被删除时会回调此方法
- (void)cache:(NSCache *)cache willEvictObject:(nonnull id)obj
{
NSLog(@"Remove Object %@", obj);
}
@end
复制代码
YYCache的基础使用
- (void)YYCacheSyncTest{
//模拟数据
NSString *value=@"I want to know who is lcj ?";
//模拟一个key
//同步方式
NSString *key=@"key";
YYCache *yyCache=[YYCache cacheWithName:@"LCJCache"];
//根据key写入缓存value
[yyCache setObject:value forKey:key];
//判断缓存是否存在
BOOL isContains=[yyCache containsObjectForKey:key];
NSLog(@"containsObject : %@", isContains?@"YES":@"NO");
//根据key读取数据
id vuale=[yyCache objectForKey:key];
NSLog(@"value : %@",vuale);
//根据key移除缓存
[yyCache removeObjectForKey:key];
//移除所有缓存
[yyCache removeAllObjects];
}
- (void)YYCacheAsyncTest{
//模拟数据
NSString *value=@"I want to know who is lcj ?";
//模拟一个key
//异步方式
NSString *key=@"key";
YYCache *yyCache=[YYCache cacheWithName:@"LCJCache"];
//根据key写入缓存value
[yyCache setObject:value forKey:key withBlock:^{
NSLog(@"setObject sucess");
}];
//判断缓存是否存在
[yyCache containsObjectForKey:key withBlock:^(NSString * _Nonnull key, BOOL contains) {
NSLog(@"containsObject : %@", contains?@"YES":@"NO");
}];
//根据key读取数据
[yyCache objectForKey:key withBlock:^(NSString * _Nonnull key, id<NSCoding> _Nonnull object) {
NSLog(@"objectForKey : %@",object);
}];
//根据key移除缓存
[yyCache removeObjectForKey:key withBlock:^(NSString * _Nonnull key) {
NSLog(@"removeObjectForKey %@",key);
}];
//移除所有缓存
[yyCache removeAllObjectsWithBlock:^{
NSLog(@"removeAllObjects sucess");
}];
//移除所有缓存带进度
[yyCache removeAllObjectsWithProgressBlock:^(int removedCount, int totalCount) {
NSLog(@"removeAllObjects removedCount :%d totalCount : %d",removedCount,totalCount);
} endBlock:^(BOOL error) {
if(!error){
NSLog(@"removeAllObjects sucess");
}else{
NSLog(@"removeAllObjects error");
}
}];
}
- (void)YYCacheLurTest{
YYCache *yyCache=[YYCache cacheWithName:@"LCJCache1"];
[yyCache.memoryCache setCountLimit:10];//内存最大缓存数据个数
[yyCache.memoryCache setCostLimit:1*1024];//内存最大缓存开销 目前这个毫无用处
[yyCache.diskCache setCostLimit:10*1024];//磁盘最大缓存开销
[yyCache.diskCache setCountLimit:10];//磁盘最大缓存数据个数
[yyCache.diskCache setAutoTrimInterval:1];//设置磁盘lru动态清理频率 默认 60秒
for(int i=0 ;i<100;i++){
//模拟数据
NSString *value=@"I want to know who is lcj ?";
//模拟一个key
NSString *key=[NSString stringWithFormat:@"key%d",i];
[yyCache setObject:value forKey:key];
}
NSLog(@"yyCache.memoryCache.totalCost:%lu",(unsigned long)yyCache.memoryCache.totalCost);
NSLog(@"yyCache.memoryCache.costLimit:%lu",(unsigned long)yyCache.memoryCache.costLimit);
NSLog(@"yyCache.memoryCache.totalCount:%lu",(unsigned long)yyCache.memoryCache.totalCount);
NSLog(@"yyCache.memoryCache.countLimit:%lu",(unsigned long)yyCache.memoryCache.countLimit);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"yyCache.diskCache.totalCost:%lu",(unsigned long)yyCache.diskCache.totalCost);
NSLog(@"yyCache.diskCache.costLimit:%lu",(unsigned long)yyCache.diskCache.costLimit);
NSLog(@"yyCache.diskCache.totalCount:%lu",(unsigned long)yyCache.diskCache.totalCount);
NSLog(@"yyCache.diskCache.countLimit:%lu",(unsigned long)yyCache.diskCache.countLimit);
for(int i=0 ;i<100;i++){
//模拟一个key
NSString *key=[NSString stringWithFormat:@"key%d",i];
id vuale=[yyCache objectForKey:key];
NSLog(@"key :%@ value : %@",key ,vuale);
}
});
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self YYCacheLurTest];
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END