iOS開發(fā)基礎(chǔ) | 被忽視和誤解的NSCache

問題一:App重啟后,NSCache中的東西還存在嗎?


一聽到緩存數(shù)據(jù),我們腦海里立馬浮現(xiàn)了《印象筆記》這樣“理所當(dāng)然”的功能:在WIFI環(huán)境中保存過的網(wǎng)絡(luò)文章,在沒有網(wǎng)絡(luò)時(比如出門在外,關(guān)閉4G),看過的文章可以繼續(xù)閱讀,并不受網(wǎng)絡(luò)關(guān)閉的影響。
NSCache可以幫助我們實現(xiàn)這樣的功能嗎?
并不能?。?!

NSCache中的數(shù)據(jù)在APP重啟(或重新init)后,都消失了,并不會保存下來。

也就是說,NSCache的正確名字應(yīng)該叫做NSMemoryCache,只是將數(shù)據(jù)保存在內(nèi)存中。

問題二:可以統(tǒng)計出NSCache中已經(jīng)緩存的數(shù)據(jù)大小嗎?


答案依然是

我們可以使用 countLimit 指定緩存中保存的對象數(shù)量
或用 totalCostLimit屬性 +
- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)num方法,勉強實現(xiàn)占用內(nèi)存的控制。

注意:cost并沒有說明必須等于對象占用的字節(jié)數(shù)。

這意味NSCache到底占用了多少內(nèi)存,是使用者(就是苦逼的我們)自己計算的!

NSCache奇葩之處三:釋放內(nèi)存時,并不確定釋放的對象的順序。


這是什么意思呢?假設(shè)我們基于NSCache實現(xiàn)一個無限上拉的列表,當(dāng)上拉到某一頁,我們存入了當(dāng)前頁的數(shù)據(jù)對象,結(jié)果觸發(fā)了內(nèi)存警告,NSCache會自動釋放,結(jié)果可能是剛存入的數(shù)據(jù)對象被清理了,而不是我們希望的“先進先出”順序。

相信讀到這里,有些童鞋已經(jīng)出離憤怒了:這個奇葩緩存有什么用?

NSCache 是線程安全的


很多童鞋第一次實現(xiàn)TableView時,都會使用NSMutableArray當(dāng)數(shù)據(jù)源,當(dāng)實現(xiàn)下拉刷新時,何時清理這個數(shù)組就很重要了,如果TableView正在刷新,而數(shù)組又被清掉時,就會導(dǎo)致數(shù)組越界訪問而崩潰,而使用NSCache就不會有此問題。

結(jié)合NSDiscardableContent協(xié)議使用


實現(xiàn)了這個協(xié)議的類需要在被引用之前,必須調(diào)用beginContentAccess來標(biāo)記為可使用的,如果在使用之前沒有調(diào)用beiginContentAccess,那么就會拋出異常。在使用結(jié)束之后,調(diào)用endContentAccess,來標(biāo)記它為可以被釋放的。如果實現(xiàn)了NSDiscardableContent協(xié)議的對象放入了NSCache中,那么,在清除它的時候,會調(diào)用discardContentIfPossible方法來判斷引用狀況,沒有引用,則銷毀。

這樣,我們就可以很“精確”地控制對象的釋放,配合NSCache的內(nèi)存自動釋放,達(dá)到既釋放過期數(shù)據(jù)的目的,又不用擔(dān)心對象過早被釋放,如果另外實現(xiàn)這樣的效果,需要做數(shù)據(jù)有效性判斷,當(dāng)然是費時費力。

另外,NSCache的KEY是不需要遵循NSCopying協(xié)議的,也就是說,作為KEY的對象并不會被拷貝,利用這點,可以做出一些NSDictionary無法實現(xiàn)的效果,請關(guān)注溪石iOS,了解更多開發(fā)技巧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容