SDWebImage异吻,有內(nèi)存和磁盤兩個(gè)緩存。內(nèi)存緩存中尔许,SDWebImage自己提供了默認(rèn)的內(nèi)存緩存類 SDMemoryCache么鹤。但是發(fā)覺(jué)這個(gè)類有幾個(gè)沒(méi)看明白。其繼承自NSCache母债。但是自己還有一個(gè)weakcache的屬性午磁。而且還是一個(gè)NSMapTable集合。
這有兩個(gè)問(wèn)題毡们,一這個(gè)weakCache是干什么迅皇,二為什么要用NSMapTable。
后來(lái)想了一下衙熔,這個(gè)應(yīng)該是保證內(nèi)存告警之后登颓,在NSCache緩存全部釋放之后,緩存對(duì)象沒(méi)有真正被釋放的緩存對(duì)象還可以通過(guò)key來(lái)讀取緩存數(shù)據(jù)红氯。
比如一個(gè)對(duì)象a框咙,a在某個(gè)頁(yè)面被強(qiáng)持有咕痛,然后同時(shí)放到一個(gè)內(nèi)存緩存SDMemoryCache(即NSCache)中,之后可以讓別人可以通過(guò)a_key來(lái)取緩存喇嘱。
但是app使用了一段時(shí)間之后內(nèi)存增加茉贡,收到了告警,這時(shí)候SDMemoryCache的操作是直接簡(jiǎn)單粗暴removeAllObject者铜,即remove父類NSCache中所有的內(nèi)容腔丧。見(jiàn)下圖
remove之后之后通過(guò)a_key查找緩存就查找不到了。但是a因?yàn)楸豁?yè)面強(qiáng)持有作烟,那么a并沒(méi)有真正釋放愉粤。緩存對(duì)象還是在內(nèi)存中存在的,但只是通過(guò)key卻查找不到了拿撩,這么看是不符合預(yù)期的衣厘。
所以針對(duì)這種情況下,可以在NSCache之外压恒,再建立一個(gè)key-value的映射表影暴,延長(zhǎng)緩存的映射表生命周期。但是這個(gè)額外的映射表他只是保證上述那種緩存并沒(méi)有真正釋放情況下涎显,延續(xù)映射關(guān)系坤检。所以使用了NSMapTable兴猩。即期吓,
一:不能在NSCache之外還強(qiáng)持有緩存對(duì)象,保證不污染原本的緩存對(duì)象生命周期倾芝。
二:只在如上述中a沒(méi)有被釋放情況下讨勤,保存key-value映射,如果value釋放了晨另,那么NSMapTable中的這個(gè)key-value映射就沒(méi)了潭千。
這種情況下,就不能使用NSDictionary借尿,需要使用NSMapTable了刨晴。
那么又有一個(gè)問(wèn)題,為什么收到內(nèi)存告警路翻,SDMemoryCache直接[super removeAllObject]狈癞?NSCache不自己處理緩存么?
NSCache自己的緩存策略是什么呢茂契?
NSCache有自己的緩存策略蝶桶,不是像上面這種簡(jiǎn)單粗暴直接remove。官網(wǎng)文檔描述掉冶,是一個(gè)智能的策略(見(jiàn)官方文檔)
蘋果的描述如下:
The?NSCache?class incorporates various auto-eviction policies, which ensure that a cache doesn’t use too much of the system’s memory. If memory is needed by other applications, these policies remove some items from the cache, minimizing its memory footprint.
然后我找了一下swift開(kāi)源中真竖,NSCache的實(shí)現(xiàn)脐雪。
https://github.com/apple/swift-corelibs-foundation/blob/master/Sources/Foundation/NSCache.swift
從上圖可知,NSCache清理緩存恢共,是根據(jù)我們預(yù)設(shè)的緩存最大值做為閾值战秋,之后每次添加新的緩存對(duì)象之后,判斷當(dāng)前緩存的總尺寸是否已經(jīng)超過(guò)了總量閾值讨韭。如果超過(guò)获询,則從最早添加的緩存對(duì)象開(kāi)始,依次移除拐袜,直到又依次滿足總量的閾值吉嚣。所以NSCache控制內(nèi)存的過(guò)程,就是一個(gè)簡(jiǎn)單粗暴的根據(jù)閾值做處理的邏輯蹬铺。沒(méi)什么智能可言尝哆,也沒(méi)有處理內(nèi)存告警。
所以到了SDMemoryCache中甜攀,才會(huì)又他自己處理內(nèi)存告警的邏輯秋泄,還有相應(yīng)的weakCache邏輯。