ios-NSCache简单介绍

NSCache是苹果提供的一套缓存机制,在AFNetworking和SDWebImage中,使用它来管理缓存。


1、NSCache和NSMutableDictionary使用起来很相似

2、这个类是线程安全的,在多线程操作中,不需要对Cache加锁,而Mutable开发的类一般都是线程不安全的,也就是说NSMutableDictionary是线程不安全的。

3、当内存不足的时候会自动的去释放内存,所以我们从缓存中取数据的时候总要判断是否为空

4、指定缓存的限额,当缓存超出限额自动释放内存

5、键对象不会像 NSMutableDictionary 中那样被复制。NScache的key只是做强引用(键不需要实现 NSCopying 协议)。

缓存数量,默认为0,没有限制

 @property NSUInteger countLimit;

缓存成本,超出上限会自动回收对象,默认为0,表示是没有限制的。

 @property NSUInteger totalCostLimit;

缓存的代理方法,缓存将要删除对象时调用,我们不能在这个方法中修改缓存。只是方便我们测试的。

//当缓存被移除的时候才会去执行其实就是将要从NSCache中移除一项的时候会执行

-(void)cache:(NSCache *)cache willEvictObject:(id)obj

{

NSLog(@"缓存移除了 %@",obj);

}

当我们限制了缓存总共可以加多少条的时候,当超过了限定的条数就会移除前面的对象。就比如说我们限定了缓存的条数为5条,我们在添加第6条的时候会先移除第1条,再去添加第6条。

苹果官方解释NSCache在系统内存很低时,会自动释放对象(但模拟器演示是不会释放的)我们通过模拟器来模拟内存警告,是没有走下面这个方法的,所以我们最好还是在收到内存警告的时候进行removeAllObject

- (void)cache:(NSCache *)cache willEvictObject:(id)obj

因为这里我们模拟了内存警告,然后在touchesBegan方法中进行获取里面存储的对象还是可以获取到的。

比如说我们在viewWillAppear中写了下面的代码

-(void)viewWillAppear:(BOOL)animated
{
    self.cache = [[NSCache alloc] init];
    [self.cache setCountLimit:3];
    self.cache.delegate = self;
    [self.cache setObject:@"AA" forKey:@"BBB"];
    [self.cache setObject:@"MMMM" forKey:@"CCC"];
}

然后点击模拟器的内存警告,然后在touchesBegin方法中写了下面的代码发现还是可以获取到的

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    
    NSLog(@"%@",[self.cache objectForKey:@"BBB"]);
          
}

当收到内存警告的时候,我们调用了removeAllObjects,无法再次从Cache中添加数据,经过在其他方法中调用removeAllObjects,而不是在内存警告中调用的removeAllObjects,则是可以再次使用的,如果再内存警告中调用了removeAllObjects,我们再往里面存入数据的话,就会出现我们一存入就会被删除

如下所示在收到内存警告的方法之后调用了removeAllObjects的时候,我们再在touchesBegan方法中做存入操作,一存入就被删除了。

这里还要注意的就是在我们把应用程序切入到后台,也是会清除所有的缓存的,也就是NSCache中的所有对象。

还有一点需要注意的就是当我们设置缓存实例时如果设置了totalCostLimit,存储对象到缓存的的方法调用必然带上了cost,否则totalCostLimit是无用的。也就是说我们应该使用下面的方法

- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;

包括在SDWebImage中存储图片到缓存中也是这样做的很好的印证了这一点。

其实关于这个问题,苹果的官方文档也是有所提到

If 0, there is no total cost limit. The default value is 0.

When you add an object to the cache, you may pass in a specified cost for the object, such as the size in bytes of the object. If adding this object to the cache causes the cache’s total cost to rise above totalCostLimit, the cache may automatically evict objects until its total cost falls below totalCostLimit. The order in which the cache evicts objects is not guaranteed.

This is not a strict limit, and if the cache goes over the limit, an object in the cache could be evicted instantly, at a later point in time, or possibly never, all depending on the implementation details of the cache.


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值