NSCache的簡單使用

簡介緩存

1)NSCache 是蘋果官方提供的緩存類,用法與 NSMutableDictionary 的用法很類似,在 AFNetworking 和 SDWebImage 中,使用它來管理緩存。安全

2)NSCache 在系統內存很低時,會自動釋放一些對象(備註:在模擬器中內存警告時,緩存不會作清理動做)。開發中爲了確保收到內存警告時真正釋放內存,最好調用 - (void)removeAllObjects; 方法。多線程

3)NSCache 是線程安全的,在多線程操做中,不須要對 NSCache 加鎖。測試

4)NSCache 的 key 只是作強引用,不須要實現 NSCopying協議atom

屬性:spa

/** 名稱 */
@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;

 

簡單實例:code

/**

* 在此提供一個例子來進行緩存使用的說明

* 需求:將字符串存入緩存,並進行查看和清理。

* 準備:在Main.storyboard中添加按鈕,分別爲添加、檢查和刪除緩存。(在此使用須要成本的方式進行測試)

*/ 

一、建立緩存對象orm

/** 緩存屬性 */
@property (nonatomic, strong) NSCache *cache;
// 經過懶加載的方式建立緩存對象
- (NSCache *)cache{
    if (!_cache) {
          _cache = [[NSCache alloc] init];
         // 設置成本爲5 當存儲的數據超過總成本數,NSCache會自動回收對象
          _cache.totalCostLimit = 5;
         // 設置代理 代理方法通常不會用到,通常是進行測試的時候使用
         _cache.delegate = self;
      }
      return _cache;
}

二、實現按鈕的點擊方法

// 添加緩存
- (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(@"清理緩存");
}

三、實現代理

#pragma mark - NSCacheDelegate
// 即將回收對象的時候進行調用,實現代理方法以前要遵照NSCacheDelegate協議。
- (void)cache:(NSCache *)cache willEvictObject:(id)obj{
       NSLog(@"回收--------%@",obj);
}

四、打印說明

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));
 }
相關文章
相關標籤/搜索