NSCache(转)

作者: RealSlimAlan | 来源:发表于2015-10-14 14:27 被阅读1233次

    今天研究SDWebimage发现,里面使用了NSCache的一个方法setObject:forKey:cost:
    首先让我们来看看什么NSCache

    NSCache

    NSCache 是苹果官方提供的缓存类,用法与 NSMutableDictionary 的用法很相似,在 AFNetworking 和 SDWebImage 中,使用它来管理缓存

    NSCache 在系统内存很低时,会自动释放一些对象

    备注:这句话源自苹果的官方文档,不过在模拟器中模拟内存警告时,缓存不会做清理动作 为了确保接收到内存警告时能够真正释放内存,最好调用一下 removeAllObjects 方法
    NSCache 是线程安全的,在多线程操作中,不需要对 Cache 加锁

    NSCache 的 Key 只是做强引用,不需要实现 NSCopying 协议

    属性

    name delegate totalCostLimit
    缓存空间的最大总成本,超出上限会自动回收对象 默认值是 0,表示没有限制
    countLimit

    能够缓存对象的最大数量 默认值是 0,表示没有限制
    evictsObjectsWithDiscardedContent

    标示缓存是否回收废弃的内容 默认值是 YES,表示自动回收

    方法

    -objectForKey: 返回与键值关联的对象 -setObject:forKey:
    在缓存中设置指定键名对应的值 与可变字典不同,缓存对象不会对键名做 copy 操作 0 成本 -

    cost是什么?

    setObject:forKey:cost: 在缓存中设置指定键名对应的值,并且指定该键值对的成本 成本 (cost) 用于计算记录在缓冲中的所有对象的总成本 置对象并指定”成本”,成本可以自行指定 啥叫成本? 例子:缓存图片 缓存 100 张图片 将图片的”宽 * 高”当作成本,图像”像素” 10M 当作缓存成本,无论缓存的多少张照片,只要像素值超过 10M,就自动清理 缓存图像的时候,使用成本,比单纯设置数量要科学!
    (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g;

    当出现内存警告时,或者超出缓存的总成本上限时,缓存会开启一个回收过程,删除部分元素

    -removeObjectForKey:

    删除缓存中,指定键名的对象

    -removeAllObjects

    删除缓存中所有对象(很可怕,最好别用)
    委托方法

    cache:willEvictObject
    缓存将要删除对象时调用 不能在此方法中修改缓存
    代码演练

    需要实现NSCacheDelegate

    @interface ViewController ()
    实现代理方法:

    // MARK: NSCache Delegate
    // 当缓存中的对象被清除的时候,会自动调用
    // obj 就是要被清理的对象
    // 提示:不建议平时开发时重写!仅供调试使用

    • (void)cache:(NSCache *)cache willEvictObject:(id)obj {
      [NSThread sleepForTimeInterval:0.5];
      NSLog(@"清除了-------> %@", obj);
      }
      声明NSCache变量:

    @property (nonatomic, strong) NSCache *cache;
    懒加载:

    • (NSCache *)cache {
      if (_cache == nil) {
      _cache = [[NSCache alloc] init];
      // 设置数量限制,最大限制为10
      _cache.countLimit = 10;
      _cache.delegate = self;
      }
      return _cache;
      }
      测试Demo:

    • (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
      for (int i = 0; i < 20; ++i) {
      NSString *str = [NSString stringWithFormat:@"hello - %04d", i];

        NSLog(@"设置 %@", str);
        // 添加到缓存
        [self.cache setObject:str forKey:@(i)];
      

      }

      // - 查看缓存内容,NSCache 没有提供遍历的方法,只支持用 key 来取值
      for (int i = 0; i < 20; ++i) {
      NSLog(@"缓存中----->%@", [self.cache objectForKey:@(i)]);
      }
      }
      运行结果:

    2015-03-25 09:27:19.953 01-NSCache演练[26010:681046] 设置 hello - 0000
    2015-03-25 09:27:19.954 01-NSCache演练[26010:681046] 设置 hello - 0001
    2015-03-25 09:27:19.954 01-NSCache演练[26010:681046] 设置 hello - 0002
    2015-03-25 09:27:19.954 01-NSCache演练[26010:681046] 设置 hello - 0003
    2015-03-25 09:27:19.954 01-NSCache演练[26010:681046] 设置 hello - 0004
    2015-03-25 09:27:19.954 01-NSCache演练[26010:681046] 设置 hello - 0005
    2015-03-25 09:27:19.954 01-NSCache演练[26010:681046] 设置 hello - 0006
    2015-03-25 09:27:19.955 01-NSCache演练[26010:681046] 设置 hello - 0007
    2015-03-25 09:27:19.955 01-NSCache演练[26010:681046] 设置 hello - 0008
    2015-03-25 09:27:19.955 01-NSCache演练[26010:681046] 设置 hello - 0009
    2015-03-25 09:27:19.955 01-NSCache演练[26010:681046] 设置 hello - 0010
    2015-03-25 09:27:20.456 01-NSCache演练[26010:681046] 清除了-------> hello - 0000
    2015-03-25 09:27:20.457 01-NSCache演练[26010:681046] 设置 hello - 0011
    2015-03-25 09:27:20.957 01-NSCache演练[26010:681046] 清除了-------> hello - 0001
    2015-03-25 09:27:20.957 01-NSCache演练[26010:681046] 设置 hello - 0012
    2015-03-25 09:27:21.458 01-NSCache演练[26010:681046] 清除了-------> hello - 0002
    2015-03-25 09:27:21.459 01-NSCache演练[26010:681046] 设置 hello - 0013
    2015-03-25 09:27:21.959 01-NSCache演练[26010:681046] 清除了-------> hello - 0003
    2015-03-25 09:27:21.959 01-NSCache演练[26010:681046] 设置 hello - 0014
    2015-03-25 09:27:22.461 01-NSCache演练[26010:681046] 清除了-------> hello - 0004
    2015-03-25 09:27:22.461 01-NSCache演练[26010:681046] 设置 hello - 0015
    2015-03-25 09:27:22.962 01-NSCache演练[26010:681046] 清除了-------> hello - 0005
    2015-03-25 09:27:22.962 01-NSCache演练[26010:681046] 设置 hello - 0016
    2015-03-25 09:27:23.464 01-NSCache演练[26010:681046] 清除了-------> hello - 0006
    2015-03-25 09:27:23.464 01-NSCache演练[26010:681046] 设置 hello - 0017
    2015-03-25 09:27:23.965 01-NSCache演练[26010:681046] 清除了-------> hello - 0007
    2015-03-25 09:27:23.965 01-NSCache演练[26010:681046] 设置 hello - 0018
    2015-03-25 09:27:24.466 01-NSCache演练[26010:681046] 清除了-------> hello - 0008
    2015-03-25 09:27:24.466 01-NSCache演练[26010:681046] 设置 hello - 0019
    2015-03-25 09:27:24.967 01-NSCache演练[26010:681046] 清除了-------> hello - 0009
    2015-03-25 09:27:24.967 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.967 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.968 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.968 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.968 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.968 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.969 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.969 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.969 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.969 01-NSCache演练[26010:681046] 缓存中----->(null)
    2015-03-25 09:27:24.969 01-NSCache演练[26010:681046] 缓存中----->hello - 0010
    2015-03-25 09:27:24.970 01-NSCache演练[26010:681046] 缓存中----->hello - 0011
    2015-03-25 09:27:24.970 01-NSCache演练[26010:681046] 缓存中----->hello - 0012
    2015-03-25 09:27:24.970 01-NSCache演练[26010:681046] 缓存中----->hello - 0013
    2015-03-25 09:27:24.970 01-NSCache演练[26010:681046] 缓存中----->hello - 0014
    2015-03-25 09:27:24.971 01-NSCache演练[26010:681046] 缓存中----->hello - 0015
    2015-03-25 09:27:24.971 01-NSCache演练[26010:681046] 缓存中----->hello - 0016
    2015-03-25 09:27:24.971 01-NSCache演练[26010:681046] 缓存中----->hello - 0017
    2015-03-25 09:27:24.971 01-NSCache演练[26010:681046] 缓存中----->hello - 0018
    2015-03-25 09:27:24.971 01-NSCache演练[26010:681046] 缓存中----->hello - 0019
    总结

    通过打印结果可以知道,当超多最大成本限制的时候,会先清除缓存中的一条数据,再存入一条新的数据。最后缓存中只能保存最大成本数的数据,即10条。

    相关文章

      网友评论

      本文标题:NSCache(转)

      本文链接:https://www.haomeiwen.com/subject/ohiocttx.html