NSCache(轉)

今天研究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條。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容