NSCache
NSCache
是蘋(píng)果官方提供的緩存類(lèi),它的用法和NSMutableDictionary
非常類(lèi)似.
NSCache
是一個(gè)類(lèi)似于集合的容器,即緩存.它存儲(chǔ)key-value,這一點(diǎn)非常類(lèi)似 NSDictionary
. 開(kāi)發(fā)者一般用 NSCache
來(lái)緩存臨時(shí)存儲(chǔ)短時(shí)間但是使用創(chuàng)建成本高的對(duì)象,重用這些對(duì)象可以優(yōu)化性能,因?yàn)樗麄兊闹挡恍枰恢匦掠?jì)算.另外一方面,這些對(duì)象對(duì)于程序來(lái)說(shuō)是不要緊的,在內(nèi)存緊張的時(shí)候會(huì)被丟棄,如果對(duì)象被丟棄了,則下次使用的時(shí)候需要重新計(jì)算.
當(dāng)一個(gè)key-value
對(duì)在緩存時(shí),緩存維護(hù)它的一個(gè)強(qiáng)引用.存儲(chǔ)在NSCache
中的通用數(shù)據(jù)類(lèi)型通常是實(shí)現(xiàn)了NSDiscardableContent
協(xié)議的對(duì)象.在緩存中存儲(chǔ)這類(lèi)對(duì)象的好處是,當(dāng)你不需要它的時(shí)候可以丟棄這些內(nèi)容,以節(jié)省內(nèi)存.默認(rèn)情況下,緩存中的NSDiscardableContent
對(duì)象在其內(nèi)容被丟棄的時(shí)候,會(huì)被移除緩存,如果一個(gè)NSDiscardableContent
被放進(jìn)緩存遣铝,則在對(duì)象被移除時(shí)暑始,緩存會(huì)調(diào)用discardContentIfPossible
方法盯拱。
NSCache
與可變集合的不同:
1.NSCache
類(lèi)結(jié)合了各種自動(dòng)刪除策略领跛,以確保不會(huì)占用過(guò)多的系統(tǒng)內(nèi)存必峰。如果其它應(yīng)用需要內(nèi)存時(shí)荒椭,系統(tǒng)自動(dòng)執(zhí)行這些策略荷科。當(dāng)調(diào)用這些策略時(shí)跃捣,會(huì)從緩存中刪除一些對(duì)象漱牵,以最大限度減少內(nèi)存的占用
2.NSCache
是線程安全的,我們可以在不同的線程中添加疚漆、刪除和查詢緩存中的對(duì)象酣胀,而不需要鎖定緩存區(qū)域。
3.不像NSMutableDictionary
對(duì)象娶聘,一個(gè)緩存對(duì)象不會(huì)拷貝key
對(duì)象闻镶。
Managing Cache Size (管理緩存大小)
@property NSUInteger countLimit
緩存應(yīng)持有的對(duì)象的最大數(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.
這不是一個(gè)嚴(yán)格的限制丸升。如果緩存的數(shù)量超過(guò)這個(gè)數(shù)量铆农,緩存中的一個(gè)對(duì)象可能會(huì)被立即丟棄、或者稍后狡耻、也可能永遠(yuǎn)不會(huì)墩剖,具體依賴(lài)于緩存的實(shí)現(xiàn)細(xì)節(jié)。
@property NSUInteger totalCostLimit
來(lái)限定緩存能維持的最大內(nèi)存,但totalCostLimit也不是一個(gè)嚴(yán)格限制
Managing Discardable Content(管理丟棄內(nèi)容)
@property BOOL evictsObjectsWithDiscardedContent
是否自動(dòng)清理緩存,默認(rèn)是YES
Adding and Removing Cached Values(存取緩存的方法)
- setObject:forKey:
- setObject:forKey:cost:
- removeObjectForKey:
- removeAllObjects
NSCacheDelegate
- (void)cache:(NSCache *)cache
willEvictObject:(id)obj
緩存將要?jiǎng)h除對(duì)象時(shí)調(diào)用夷狰,不能在此方法中修改緩存岭皂。
實(shí)踐
- (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個(gè)",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(@"被刪除的對(duì)象是:%@",obj);
}
從運(yùn)行結(jié)果能看出,
_cache
只保存了最新的5個(gè)字符串,最先加入的5個(gè)字符串后來(lái)被刪除掉了,但是文檔也指出了countLimit并不是一個(gè)嚴(yán)格的限制,如果cache數(shù)量超出了limit,那么cache中的對(duì)象有可能立刻被清理出去,或者稍后,或者永遠(yuǎn)都不會(huì)被清理掉,而這個(gè)時(shí)機(jī)依賴(lài)于cache的實(shí)現(xiàn)細(xì)節(jié)