NSCache 是蘋果官方提供的緩存類,用法與 NSMutableDictionary 的用法很相似,在 AFNetworking 和 SDWebImage 中,使用它來管理緩存
NSCache 在系統內存很低時,會自動釋放一些對象
備注:這句話源自蘋果的官方文檔,不過在模擬器中模擬內存警告時,緩存不會做清理動作 為了確保接收到內存警告時能夠真正釋放內存,最好調用一下 removeAllObjects 方法NSCache 是線程安全的,在多線程操作中,不需要對 Cache 加鎖
NSCache 的 Key 只是做強引用,不需要實現 NSCopying 協議
countLimit
能夠緩存對象的最大數量 默認值是 0,表示沒有限制evictsObjectsWithDiscardedContent
標示緩存是否回收廢棄的內容 默認值是 YES,表示自動回收(void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g;
當出現內存警告時,或者超出緩存的總成本上限時,緩存會開啟一個回收過程,刪除部分元素
-removeObjectForKey:
刪除緩存中,指定鍵名的對象
-removeAllObjects
刪除緩存中所有對象(很可怕,最好別用)需要實現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條。