YYCache小编也是通过网络上面的介绍,对其进行基本的使用,希望能帮助到大家,下面小编不会对起其源码进行介绍如果大家想研究其内部的代码可以看看这篇博客写的非常不错:http://www.jianshu.com/p/b8dcf6634fab。
YYCache的下载地址:https://github.com/ibireme/YYCache.git
1. 内存缓存(YYMemoryCache)
存储的单元是_YYLinkedMapNode,除了key和value外,还存储了它的前后Node的地址_prev,_next.整个实现基于_YYLinkedMap,它是一个双向链表,除了存储了字典_dic外,还存储了头结点和尾节点.它实现的功能很简单,就是:有新数据了插入链表头部,访问过的数据结点移到头部,内存紧张时把尾部的结点移除.就这样实现了淘汰算法.因为内存访问速度很快,锁占用的时间少,所以用的速度最快的OSSpinLockLock
2. 硬盘缓存(YYDiskCache)
采用的是文件和数据库相互配合的方式.有一个参数inlineThreshold,默认20KB,小于它存数据库,大于它存文件.能获得效率的提高.key:path,value:cache存储在NSMapTable里.根据path获得cache,进行一系列的set,get,remove操作更底层的是YYKVStorage,它能直接对sqlite和文件系统进行读写.每次内存超过限制时,select key, filename, size from manifest order by last_access_time desc limit ?1会根据时间排序来删除最近不常用的数据.硬盘访问的时间比较长,如果用OSSpinLockLock锁会造成CPU消耗过大,所以用的dispatch_semaphore_wait来做.
@interface YYCache : NSObject
// 读取当前数据库名称
@property (copy, readonly) NSString *name;
// memoryCache内存缓存,diskCache文件缓存
@property (strong, readonly) YYMemoryCache *memoryCache;
@property (strong, readonly) YYDiskCache *diskCache;
// 可通过下面三种方法来实例化YYCache对象
- (nullable instancetype)initWithName:(NSString *)name;
- (nullable instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
+ (nullable instancetype)cacheWithPath:(NSString *)path;
// 禁止通过下面两个方式实例化对象
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new __attribute__((unavailable("new方法不可用,请用initWithName:")));
// 通过key判断是否缓存了某个东西,第二个法是异步执行,异步回调
- (BOOL)containsObjectForKey:(NSString *)key;
- (void)containsObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, BOOL contains))block;
// 读--通过key读取缓存,第二个法是异步执行,异步回调
- (nullable id
- (void)objectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, id
// 增、改--缓存对象(可缓存遵从NSCoding协议的对象),第二个法是异步执行,异步回调
- (void)setObject:(nullable id
- (void)setObject:(nullable id
// 删--删除缓存
- (void)removeObjectForKey:(NSString *)key;
- (void)removeObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key))block;
- (void)removeAllObjects;
- (void)removeAllObjectsWithBlock:(void(^)(void))block;
- (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress
endBlock:(nullable void(^)(BOOL error))end;
@end
下边直接上小编写的代码:
#import
//同步存储
- (void)synchronizingStorageForCache{
NSString * values = @"who is FLS";
NSString * key = @"fls";
NSArray * arr = @[@"1",@"2",@"3",@"4"];
NSString * key2 = @"arr1";
YYCache * cache = [YYCachecacheWithName:@"FLSCache"];
// �� 缓存实现,默认同时进行内存缓存与文件缓存
[cache setObject:values forKey:key];
[cache setObject:arr forKey:key2];
// [cache.memoryCache setObject:values forKey:key];//只缓存在内存
// [cache.diskCache setObject:values forKey:key];//只缓存在文件
//判断是否存在
BOOL success = [cache containsObjectForKey:key2];
NSLog(@"%@",success?@"YES":@"NO");
id obj = [cache objectForKey:key2];
NSLog(@"%@",obj);
NSLog(@"%@",cache.name);
// [cache removeObjectForKey:key];//更具key删除
// [cache removeAllObjects];//删除全部
}
//异步存储
- (void)asynchronousStorageForCache{
//模拟数据
NSString *value=@"I want to know who is FLS ?";
//模拟一个key
//异步方式
NSString *key=@"key";
YYCache *yyCache=[YYCachecacheWithName:@"FLSCache"];
//根据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");
}
}];
}
//定时清理
//YYCache和PINCache一样并没有实现基于最大内存开销进行LRU,不过YYCache实现了最大缓存数据个数进行LRU清理,这一点也是选择YYCache原因之一,对于YYCache磁盘LRU清理并不是及时清理,而是后台开启一个定时任务进行RLU清理操作,定时时间默认是60s。
- (void)LruDataCache{
YYCache *yyCache=[YYCachecacheWithName:@"FLSCache"];
[yyCache.memoryCache setCountLimit:50];//内存最大缓存数据个数
[yyCache.memoryCachesetCostLimit:1*1024];//内存最大缓存开销 目前这个毫无用处
[yyCache.diskCache setCostLimit:10*1024];//磁盘最大缓存开销
[yyCache.diskCache setCountLimit:50];//磁盘最大缓存数据个数
[yyCache.diskCachesetAutoTrimInterval:60];//设置磁盘lru动态清理频率 默认 60秒
for(int i=0 ;i<100;i++){
//模拟数据
NSString *value=@"I want to know who is FLS ?";
//模拟一个key
NSString *key=[NSStringstringWithFormat:@"key%d",i];
[yyCache setObject:value forKey:key];
}
NSLog(@"��yyCache.memoryCache.totalCost:%lu",(unsignedlong)yyCache.memoryCache.totalCost);
NSLog(@"��yyCache.memoryCache.costLimit:%lu",(unsignedlong)yyCache.memoryCache.costLimit);
NSLog(@"��yyCache.memoryCache.totalCount:%lu",(unsignedlong)yyCache.memoryCache.totalCount);
NSLog(@"��yyCache.memoryCache.countLimit:%lu",(unsignedlong)yyCache.memoryCache.countLimit);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(120 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
NSLog(@"����yyCache.diskCache.totalCost:%lu",(unsignedlong)yyCache.diskCache.totalCost);
NSLog(@"����yyCache.diskCache.costLimit:%lu",(unsignedlong)yyCache.diskCache.costLimit);
NSLog(@"����yyCache.diskCache.totalCount:%lu",(unsignedlong)yyCache.diskCache.totalCount);
NSLog(@"����yyCache.diskCache.countLimit:%lu",(unsignedlong)yyCache.diskCache.countLimit);
for(int i=0 ;i<100;i++){
//模拟一个key
NSString *key=[NSStringstringWithFormat:@"key%d",i];
id vuale=[yyCache objectForKey:key];
NSLog(@"key :%@ value : %@",key ,vuale);
}
});
}