NSCache
NSCache
是蘋果官方提供的緩存類,它的用法和NSMutableDictionary
非常類似.
NSCache
是一個類似于集合的容器,即緩存.它存儲key-value,這一點非常類似 NSDictionary
. 開發(fā)者一般用 NSCache
來緩存臨時存儲短時間但是使用創(chuàng)建成本高的對象,重用這些對象可以優(yōu)化性能,因為他們的值不需要被重新計算.另外一方面,這些對象對于程序來說是不要緊的,在內(nèi)存緊張的時候會被丟棄,如果對象被丟棄了,則下次使用的時候需要重新計算.
當(dāng)一個key-value
對在緩存時,緩存維護(hù)它的一個強(qiáng)引用.存儲在NSCache
中的通用數(shù)據(jù)類型通常是實現(xiàn)了NSDiscardableContent
協(xié)議的對象.在緩存中存儲這類對象的好處是,當(dāng)你不需要它的時候可以丟棄這些內(nèi)容,以節(jié)省內(nèi)存.默認(rèn)情況下,緩存中的NSDiscardableContent
對象在其內(nèi)容被丟棄的時候,會被移除緩存,如果一個NSDiscardableContent
被放進(jìn)緩存,則在對象被移除時,緩存會調(diào)用discardContentIfPossible
方法。
NSCache
與可變集合的不同:
1.NSCache
類結(jié)合了各種自動刪除策略,以確保不會占用過多的系統(tǒng)內(nèi)存。如果其它應(yīng)用需要內(nèi)存時,系統(tǒng)自動執(zhí)行這些策略。當(dāng)調(diào)用這些策略時,會從緩存中刪除一些對象,以最大限度減少內(nèi)存的占用
2.NSCache
是線程安全的,我們可以在不同的線程中添加、刪除和查詢緩存中的對象,而不需要鎖定緩存區(qū)域。
3.不像NSMutableDictionary
對象,一個緩存對象不會拷貝key
對象。
Managing Cache Size (管理緩存大小)
@property NSUInteger countLimit
緩存應(yīng)持有的對象的最大數(shù)量。
This is not a strict limit—if the cache goes over the limit, an object in the cache could be evicted instantly, later, or possibly never, depending on the implementation details of the cache.
這不是一個嚴(yán)格的限制。如果緩存的數(shù)量超過這個數(shù)量,緩存中的一個對象可能會被立即丟棄、或者稍后、也可能永遠(yuǎn)不會,具體依賴于緩存的實現(xiàn)細(xì)節(jié)。
@property NSUInteger totalCostLimit
來限定緩存能維持的最大內(nèi)存,但totalCostLimit也不是一個嚴(yán)格限制
Managing Discardable Content(管理丟棄內(nèi)容)
@property BOOL evictsObjectsWithDiscardedContent
是否自動清理緩存,默認(rèn)是YES
Adding and Removing Cached Values(存取緩存的方法)
- setObject:forKey:
- setObject:forKey:cost:
- removeObjectForKey:
- removeAllObjects
NSCacheDelegate
- (void)cache:(NSCache *)cache
willEvictObject:(id)obj
緩存將要刪除對象時調(diào)用,不能在此方法中修改緩存。
實踐
- (NSCache *)cache
{
if (_cache == nil) {
_cache = [[NSCache alloc] init];
_cache.delegate = self;
}
return _cache;
}
self.cache.countLimit = 5;
for (int i = 0; i < 10; i++) {
NSString *str = [NSString stringWithFormat:@"我是第%d個",i];
[_cache setObject:str forKey:[NSString stringWithFormat:@"%d",i] ];
}
NSString *str = [_cache objectForKey:@"0"];
NSLog(@"str0:%@",str);
str = [_cache objectForKey:@"5"];
NSLog(@"str5:%@",str);
str = [_cache objectForKey:@"6"];
NSLog(@"str6:%@",str);
str = [_cache objectForKey:@"7"];
NSLog(@"str7:%@",str);
- (void)cache:(NSCache *)cache willEvictObject:(nonnull id)obj
{
NSLog(@"被刪除的對象是:%@",obj);
}
從運行結(jié)果能看出,
_cache
只保存了最新的5個字符串,最先加入的5個字符串后來被刪除掉了,但是文檔也指出了countLimit并不是一個嚴(yán)格的限制,如果cache數(shù)量超出了limit,那么cache中的對象有可能立刻被清理出去,或者稍后,或者永遠(yuǎn)都不會被清理掉,而這個時機(jī)依賴于cache的實現(xiàn)細(xì)節(jié)