NSCache的使用

本篇文章首先会详细讲解NSCache的基本使用,NSCache是Foundation框架提供的缓存类的实现,使用方式类似于可变字典,由于NSMutableDictionary的存在,很多人在实现缓存时都会使用可变字典,但NSCache在实现缓存功能时比可变字典更方便,最重要的是它是线程安全的,而NSMutableDictionary不是线程安全的,在多线程环境下使用NSCache是更好的选择。接着,会通过源码讲解SDWebImage的缓存策略。

NSCache和NSMutableDictionary对比
NSCache的使用很方便,提供了类似可变字典的使用方式,但它比可变字典更适用于实现缓存,最重要的原因为NSCache是线程安全的,使用NSMutableDictionary自定义实现缓存时需要考虑加锁和释放锁,NSCache已经帮我们做好了这一步。其次,在内存不足时NSCache会自动释放存储的对象,不需要手动干预,如果是自定义实现需要监听内存状态然后做进一步的删除对象的操作。还有一点就是NSCache的键key不会被复制,所以key不需要实现NSCopying协议。

1.NSCache是苹果官方提供的缓存类,具体使用和NSDictionary类似,在AFN和SDWebImage框架中被使用类管理缓存
2.苹果官方解释NSCache在系统内存很低时,会自动释放对象
3.NSCache是线程安全的,在多线程操作中,不需要对NSCache加锁
4.NSCache的key只是对对象进行strong引用,不是拷贝

上面讲解的三点就是NSCache相比于NSMutableDictionary实现缓存功能的优点,在需要实现缓存时应当优先考虑使用NSCache。

首先看一下NSCache提供的属性和相关方法:

//名称
@property (copy) NSString *name;

//NSCacheDelegate代理
@property (nullable, assign) id<NSCacheDelegate> delegate;

//缓存空间的最大总成本,超出上限会自动回收对象,默认值为0,表示没有限制
@property totalCostLimit;

//能够缓存的对象的最大数量,默认值为0,表示没有限制
@property countLimit

//表示缓存是否回收废弃的内容
@property evictsObjectsWithDiscardedContent;

//通过key获取value,类似于字典中通过key取value的操作
- (nullable ObjectType)objectForKey:(KeyType)key;

//设置key、value
- (void)setObject:(ObjectType)obj forKey:(KeyType)key; // 0 cost

/*
设置key、value
cost表示obj这个value对象的占用的消耗?可以自行设置每个需要添加进缓存的对象的cost值
这个值与后面的totalCostLimit对应,如果添加进缓存的cost总值大于totalCostLimit就会自动进行删除
感觉在实际开发中直接使用setObject:forKey:方法就可以解决问题了
*/
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;

//根据key删除value对象
- (void)removeObjectForKey:(KeyType)key;

//删除保存的所有的key-value
- (void)removeAllObjects;

/*
NSCache能够占用的消耗?的限制
当NSCache缓存的对象的总cost值大于这个值则会自动释放一部分对象直到占用小于该值
非严格限制意味着如果保存的对象超出这个大小也不一定会被删除
这个值就是与前面setObject:forKey:cost:方法对应
*/
@property NSUInteger totalCostLimit;    // limits are imprecise/not strict

/*
缓存能够保存的key-value个数的最大数量
当保存的数量大于该值就会被自动释放
非严格限制意味着如果超出了这个数量也不一定会被删除
*/
@property NSUInteger countLimit;    // limits are imprecise/not strict
/*
这个值与NSDiscardableContent协议有关,默认为YES
当一个类实现了该协议,并且这个类的对象不再被使用时意味着可以被释放
*/
@property BOOL evictsObjectsWithDiscardedContent;

@end

//NSCacheDelegate协议
@protocol NSCacheDelegate <NSObject>
@optional
//上述协议只有这一个方法,缓存中的一个对象即将被删除时被回调
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;
@end

通过接口可以看出,NSCache提供的方法都很简单,属性的意义也很明确,接下来举一个简单的栗子:

@property (nonatomic, strong) NSCache *cache;
-(NSCache *)cache
{
   if(_cache == nil){
      _cache = [[NSCache alloc] init];
      _cache.totalCostLimit = 5;  //如果发现存的数据超过总成本,会自动回收之前的对象
   }
   return _cache;
}

-(IBAction)addBtnClick:(id)sender{
//NSData只是对对象进行强引用,而不是拷贝,如果把循环中的第一行放在外面,就不会回收对象了,因为只有一个对象,key只是对这一个对象的引用。而回收对象看的是对象的个数,而不是引用的个数,所以不会回收对象。
    for(NSInteger i = 0; i < 10; i++){
       NSData *data = [NSData dataWithContentsOffFile:@""];
       [self.cache setObject:data forKey:@(i) cost:1];
    }
}
-(IBAction)checkBtnClick:(id)sender{
    for(NSInteger i = 0; i < 10; i++){
       NSData *data = [self.cache objectForKey:data forKey:@(i)];
       if(data){
           NSLog(@"取出数据");
       } 
    }
}
-(IBAction)removeBtnClick:(id)sender{
    for(NSInteger i = 0; i < 10; i++){
       [self.cache removeAllObject]; 
    }
}
//代理方法  即将回收对象的时候调用这个方法
-(void)cache:(NSCache  *)cache willEvictObject:(id)obj
{
   NSLog(@"回收对象");
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值