iOS开发-NSCache

时间:2022-04-01 18:49:47

开发时,经常会遇到一个问题,从网络下载的图片应该如何来缓存?难道每次请求都要去下载一次?流量不要钱哇?所以比较好的方法就是把图片资源下载下来,保存到本地,然后下次直接从本地取出图片就可以了,但是用什么来保存这个图片呢?有些人可能说用NSDictionary(应该是NSMutableDictionary),因为这个类在开发中非常非常常用。但是其实可能有一个更好的选择,是专门为缓存来设计的,没错,就是NSCache。非常牛逼的AFN、SDWebImage都是用它来进行图片缓存的。

就像上边说到的,NSCache和NSDictionary很类似,用key-value键值对来存储,但是相对于NSDictionary,他有几点优势:

  • 1.NSCache结合了各种自动删除的策略,用来确保不会占用过多的系统内存。
  • 2.NSCache是线程安全的,在多线程情况下,不需要考虑加锁来保证数据的安全。
  • 3.不像NSMutableDictionary,NSCache不会copy对象,而是保留它。

NSCache 框架

NSCache的类中内容很少,从Xcode进去看也就只有43行,接下来我们来看一下他都提供了哪些方法和属性。

NSCache 的属性

      
       1
      
      
       @property NSUInteger countLimit;	
      

countLimit用来限制缓存最多维护的对象个数,默认为0,0表示不限制数量。
但是需要注意的是,这个限制并不是严格的限制,如果缓存的数量超过这个数量,缓存中的一个对象可能会被立即丢弃,也可能稍候丢弃,还可能永远都不会丢弃,具体还要看实现的方式。

      
       1
      
      
       @property NSUInteger totalCostLimit;	
      

totalCostLimit用来限制缓存最大能够维持的内存,默认也为0,表示没有限制。
一般我们会使用字节来作为cost进行限制,在添加缓存时可以指定写入的缓存的cost,当总消耗的cost值超过限制时,就会释放一些缓存对象,这个释放对象的选择使用LRU(Least Recently Used)算法来选择最近没有使用的对象进行淘汰。

NSCache 方法

NSCache的存取方法主要是用key-value的形式,存取方法分为set、get、remove三种类型。

      
       1
      
      
       2
      
      
       3
      
      
       4
      
      
       5
      
      
       6
      
      
       - 
       (nullable ObjectType)objectForKey:
       (KeyType)key;
      
      
       - 
       (void)setObject:
       (ObjectType)obj forKey:
       (KeyType)key; 
       // 0 cost
      
      
       - 
       (void)setObject:
       (ObjectType)obj forKey:
       (KeyType)key cost:
       (NSUInteger)g;
      
      
       - 
       (void)removeObjectForKey:
       (KeyType)key;
      
      
      
       - 
       (void)removeAllObjects;
      

其中

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

可以指定消耗的cost,配合之前的totalCostLimit来管理缓存大小。

NSCacheDelegate

NSCacheDelegate只有一个方法:

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

当代理对象即将从缓存中移除时激活。

NSCache 使用

NSCache的使用很简单。

实例化一个cache对象,然后设定缓存内容就可以了,但是我们

      
       1
      
      
       2
      
      
       3
      
      
       4
      
      
       5
      
      
       6
      
      
       7
      
      
       8
      
      
       9
      
      
       10
      
      
       11
      
      
       12
      
      
       13
      
      
       14
      
      
       15
      
      
       16
      
      
       17
      
      
       18
      
      
       self.myCache = [[
       NSCache alloc] init];
      
      
       self.myCache.delegate = 
       self;
      
      
      
       //设置最大缓存数量:10
      
      
       self.myCache.countLimit = 
       10;
      
      
       //设置最大缓存cost:5M
      
      
       self.myCache.totalCostLimit = 
       5 * 
       1024 * 
       1024;
      
      
      
       for(
       NSInteger i = 
       0 ; i < 
       100 ; i   )
      
      
       {
      
          
      
          
       UIImage *image = [
       UIImage imageNamed:
       @"111.jpg"];
      
          
       NSData *data = 
       UIImageJPEGRepresentation(image, 
       1.0);
      
      
          
       NSString *keyStr = [
       NSString stringWithFormat:
       @"image%ld",i];
      
          
      
      
           [
       self.myCache setObject:data forKey:keyStr];
      
      
       }
      

然后添加一个按钮,在点击时获取缓存

      
       1
      
      
       2
      
      
       3
      
      
       4
      
      
       5
      
      
       6
      
      
       7
      
      
       8
      
      
       9
      
      
       10
      
      
       11
      
      
       12
      
      
       13
      
      
       - (
       IBAction)getBtnClicked:(
       id)sender
      
      
       {
      
          
       for(
       NSInteger i = 
       0 ; i < 
       100 ; i   )
      
      
           {
      
              
       NSString *keyStr = [
       NSString stringWithFormat:
       @"image%ld",i];
      
              
      
              
       NSData *data = [
       self.myCache objectForKey:keyStr];
      
              
      
              
       NSLog(
       @"%ld",[data length]);
      
              
      
      
           }
      
      
      
       }
      

可以看到打印出来的内容:

      
       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
      
      
       ...
      
      
       2018-04-08 
       17:
       41:
       16.916639 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.916978 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:16.917196 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.917504 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.917818 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.918076 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.918456 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.918640 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.918945 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:16.919214 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.919521 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.919740 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.920067 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.920571 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.920829 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.921340 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.921631 
       0800 CacheDemo[
       56627:
       2584885] 
       0
      
      
       2018-04-08 
       17:
       41:
       16.921903 
       0800 CacheDemo[
       56627:
       2584885] 
       9132462
      
      
       2018-04-08 
       17:
       41:16.922146 
        大专栏  iOS开发-NSCache0800 CacheDemo[
       56627:
       2584885] 
       9132462
      
      
       2018-04-08 
       17:
       41:
       16.922386 
       0800 CacheDemo[
       56627:
       2584885] 
       9132462
      
      
       2018-04-08 
       17:
       41:
       16.922575 
       0800 CacheDemo[
       56627:
       2584885] 
       9132462
      
      
       2018-04-08 
       17:
       41:
       16.922783 
       0800 CacheDemo[
       56627:
       2584885] 
       9132462
      
      
       2018-04-08 
       17:
       41:
       16.923082 
       0800 CacheDemo[
       56627:
       2584885] 
       9132462
      
      
       2018-04-08 
       17:
       41:
       16.923476 
       0800 CacheDemo[
       56627:
       2584885] 
       9132462
      
      
       2018-04-08 
       17:
       41:
       16.923756 
       0800 CacheDemo[
       56627:
       2584885] 
       9132462
      
      
       2018-04-08 
       17:
       41:
       16.923991 
       0800 CacheDemo[
       56627:
       2584885] 
       9132462
      
      
       2018-04-08 
       17:
       41:
       16.924333 
       0800 CacheDemo[
       56627:
       2584885] 
       9132462
      

发现还是有10个图片被保存了下来,这时候我们把限制的cost大小和存入cost的方法修改一下。

      
       1
      
      
       2
      
      
       3
      
      
       4
      
      
       5
      
      
       6
      
      
       7
      
      
       8
      
      
       9
      
      
       10
      
      
       11
      
      
       12
      
      
       13
      
      
       14
      
      
       15
      
      
       16
      
      
       17
      
      
       18
      
      
       19
      
      
       20
      
          
       self.myCache = [[
       NSCache alloc] init];
      
          
       self.myCache.delegate = 
       self;
      
          
      
          
       //设置最大缓存数量:10
      
          
       self.myCache.countLimit = 
       10;
      
          
       //设置最大缓存cost:10M
      
          
       self.myCache.totalCostLimit = 
       10 * 
       1024 * 
       1024;
      
          
      
          
       for(
       NSInteger i = 
       0 ; i < 
       100 ; i   )
      
      
           {
      
              
      
              
       UIImage *image = [
       UIImage imageNamed:
       @"111.jpg"];
      
              
       NSData *data = 
       UIImageJPEGRepresentation(image, 
       1.0);
      
      
              
       NSString *keyStr = [
       NSString stringWithFormat:
       @"image%ld",i];
      
              
      
      
       // [self.myCache setObject:data forKey:keyStr];
      
              
       //存入时添加cost
      
      
               [
       self.myCache setObject:data forKey:keyStr cost:[data length]];
      
      
           }
      

打印结果:

      
       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
      
      
       2018-04-08 
       17:
       43:
       36.566623 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.566814 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.567049 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.567326 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.567738 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:36.568164 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.568451 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.568780 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:36.569227 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.569489 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.569771 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.569993 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.570265 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.570518 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.570832 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.571092 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.571305 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.571526 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.571921 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.572595 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.572763 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.572979 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.573266 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.573541 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.573775 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.573969 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:36.574232 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.574565 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:36.575234 
       0800 CacheDemo[
       56686:
       2587750] 
       0
      
      
       2018-04-08 
       17:
       43:
       36.575364 
       0800 CacheDemo[
       56686:
       2587750] 
       9132462
      

发现只有最后一次的图片被缓存下来了。

最后

以上就是NSCache的全部内容了,这个类中的内容不多,但是可能会在开发时帮助我们解决很多麻烦的问题。