zoukankan      html  css  js  c++  java
  • NSCache的简单使用

    简介

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

    2)NSCache 在系统内存很低时,会自动释放一些对象(备注:在模拟器中内存警告时,缓存不会做清理动作)。开发中为了确保收到内存警告时真正释放内存,最好调用 - (void)removeAllObjects; 方法。

    3)NSCache 是线程安全的,在多线程操作中,不需要对 NSCache 加锁。

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

    属性:

    /** 名称 */
    @property (copy) NSString *name;
    /** 代理 */
    @property (nullable, assign) id<NSCacheDelegate> delegate;
    /** 缓存空间的最大总成本,超出上限会自动回收对象,默认值是 0,表示没有限制 */
    @property NSUInteger totalCostLimit;
    /** 能够缓存对象的最大数量,默认值是 0,表示没有限制 */
    @property NSUInteger countLimit;
    /** 标识缓存是否回收废弃的内容,默认值是 YES,表示自动回收 */
    @property BOOL evictsObjectsWithDiscardedContent;

    方法:

    /** 
     返回与键值关联的对象
     */
    - (nullable ObjectType)objectForKey:(KeyType)key;
    
    /** 
     在缓存中设置指定键名对应的值,与可变字典不同,缓存对象不会对键名做 copy 操作,0 成本
     */
    - (void)setObject:(ObjectType)obj forKey:(KeyType)key;
    
    /** 
     在缓存中设置指定键名对应的值,并且指定该键值对的成本。当出现内存警告时,或者超出缓存的总成本上限时,缓存会开启一个回收过程,删除部分元素
     @param cost 成本 (cost) 用于计算记录在缓冲中的所有对象的总成本
     */
    - (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;
    
    /** 
     删除缓存中,指定键名的对象
     */
    - (void)removeObjectForKey:(KeyType)key;
    
    /** 
     删除缓存中所有对象
     */
    - (void)removeAllObjects;

    委托方法:

    /** 
     缓存将要删除对象时调用,注意:不能在此方法中修改缓存!!
     */
    - (void)cache:(NSCache *)cache willEvictObject:(id)obj;

    简单实例:

    /**
    
    * 在此提供一个例子来进行缓存使用的说明
    
    * 需求:将字符串存入缓存,并进行查看和清理。
    
    * 准备:在Main.storyboard中添加按钮,分别为添加、检查和删除缓存。(在此使用需要成本的方式进行测试)
    
    */ 

    1、创建缓存对象

    /** 缓存属性 */
    @property (nonatomic, strong) NSCache *cache;
    // 通过懒加载的方式创建缓存对象
    - (NSCache *)cache{
        if (!_cache) {
              _cache = [[NSCache alloc] init];
             // 设置成本为5 当存储的数据超过总成本数,NSCache会自动回收对象
              _cache.totalCostLimit = 5;
             // 设置代理 代理方法一般不会用到,一般是进行测试的时候使用
             _cache.delegate = self;
          }
          return _cache;
    }

    2、实现按钮的点击方法

    // 添加缓存
    - (IBAction)addCache {
           for (int i = 0 ; i < 10 ; i++) {
                NSString *str = [NSString stringWithFormat:@"在这里进行了存储数据"];
                 // 设置成本数为1
                [self.cache setObject:str forKey:@(i) cost:1];
                 NSLog(@"存储数据----%@",@(i));
              }
    }
    // 检查缓存
    - (IBAction)checkCache {
               NSLog(@"---------------------------------------------");
                for (int i = 0; i < 10 ; i++) {
                NSString *str = [self.cache objectForKey:@(i)];
                          if (str) {
                                     NSLog(@"取出缓存中存储的数据-----%@",@(i));
                            }
                 }
    }
    // 清理缓存
    - (IBAction)deleteCache {
          [self.cache removeAllObjects];
           NSLog(@"清理缓存");
    }

    3、实现代理

    #pragma mark - NSCacheDelegate
    // 即将回收对象的时候进行调用,实现代理方法之前要遵守NSCacheDelegate协议。
    - (void)cache:(NSCache *)cache willEvictObject:(id)obj{
           NSLog(@"回收--------%@",obj);
    }

    4、打印说明

    4.1 点击添加按钮的打印
    
    存储数据----0
    
    存储数据----1
    
    存储数据----2
    
    存储数据----3
    
    存储数据----4
    
    回收--------在这里进行了存储数据
    
    存储数据----5
    
    回收--------在这里进行了存储数据
    
     存储数据----6
    
     回收--------在这里进行了存储数据
    
     存储数据----7
    
    回收--------在这里进行了存储数据
    
    存储数据----8
    
    回收--------在这里进行了存储数据
    
    存储数据----9
    
    4.2 点击检查按钮的打印
    
     ---------------------------------------------
    
    取出缓存中存储的数据-----5
    
     取出缓存中存储的数据-----6
    
    取出缓存中存储的数据-----7
    
     取出缓存中存储的数据-----8
    
    取出缓存中存储的数据-----9
    
    4.3 打印相关的解释
    
    在此因为进行每个字符串对象存储时,成本是1,我们设置的总成本是5,字符串对象存储了10次,总成本是10,所以在存储数据5的时候会回收数据1的字符串对象,以此类推,所以打印的结果如上所示。关于清理缓存和其他相关的操作由读者们自行打印,在此不做赘述了。

    补充:

    /**
    
    *  如果把例子中的添加缓存写成如下方式,就不会存在回收的打印,在检查缓存的时候也会有10条数据。
    
    *  解释:NSCache的Key只是对对象进行了Strong引用,而非拷贝。
    
    *  当写在for循环外部时,所以对于字符串对象只是在内存中建立了10个强引用,而存储的真正的字符串对象只有一个(字符串对象只创建了一次),所以总成本为1。
    
    *  当写在for循环内部时,字符串对象只是在内存中建立了10个强引用,而存储的真正的字符串对象有十个(每次都在创建新的字符串对象),所以总成本为10。
    
    */
    
    // 添加缓存
    - (IBAction)addCache {
              // NSCache的Key只是对对象进行了Strong引用,而非拷贝,
               NSString *str = [NSString stringWithFormat:@"在这里进行了存储数据"];
                for (int i = 0 ; i < 10 ; i++) {
                // 设置成本数为1
                [self.cache setObject:str forKey:@(i) cost:1];
                NSLog(@"存储数据----%@",@(i));
     }
  • 相关阅读:
    [置顶] java 通过classloader加载类再通过classforname实例化
    Linux内核源代码解析——用户发送数据包的起源之sendto
    POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203
    add-two-numbers-ii
    【转载】React初学者入门须知
    【Todo】【转载】ES6的学习记录
    【转载】Java中如何写一段内存泄露的程序 & ThreadLocal 介绍和使用
    【Todo】深入理解Javascript系列
    【转载】什么是优秀技术团队
    【转载】React入门-Todolist制作学习
  • 原文地址:https://www.cnblogs.com/weiming4219/p/8186250.html
Copyright © 2011-2022 走看看