iOS緩存框架-PINCache解讀

在項目中總是需要緩存一些網絡請求數據以減輕服務器壓力,業內也有許多優秀的開源的解決方案。通常的緩存方案都是由內存緩存和磁盤緩存組成的,內存緩存速度快容量小,磁盤緩存容量大速度慢可持久化。常見的內存緩存有NSCache、TMMemoryCachePINMemoryCacheYYMemoryCache。常見的磁盤緩存有TMDiskCache、PINDiskCache、SDWebImage。這次解讀先從PINCache這個優秀的開源項目開始。PINCache項目是在Tumblr 宣佈不在維護 TMCache 後,由 Pinterest 維護和改進的基於TMCache的一個內存緩存,修復了TMCache存在的性能和死鎖問題,可以說是有了一個較大的提升。

PINCache概論

PINCache是多線程安全的,使用鍵值對來保存數據。PINCache內部包含了2個類似的對象屬性,一個是內存緩存PINMemoryCache,另一個是磁盤緩存PINDiskCache。PINCache本身並沒有過多的做處理緩存的具體工作,而是全部交給它內部的2個對象屬性來實現,它只是對外提供了一些同步或者異步接口。在iOS中,當App收到內存警告或者進入後臺的時候,PINCache能夠清理掉所有的內存緩存。

PINCache使用

採用PINCache項目的Demo來說明,這個是從服務器加載數據,再緩存下來,繼而做業務邏輯處理,如果下次還需要同樣的數據,要是緩存裏面還有這個數據的話,那麼就不需要再次發起網絡請求了,而是直接使用這個數據。PINCache除了可以按鍵取值、按鍵存值、按鍵刪值之外,還可以移除某個日期之前的緩存數據、刪除所有緩存、限制緩存大小等。

[[PINCache sharedCache] objectForKey:[url absoluteString] block:^(PINCache cache, NSString key, id object) {
if (object) {
//有緩存,在這裏做業務邏輯處理
return;
}
//沒有緩存,那麼去服務器加載數據,存入緩存,做業務邏輯處理
NSLog(@"cache miss, requesting %@", url);
[[PINCache sharedCache] setObject:data forKey:[url absoluteString]];
}];

PINCache結構


PINCache

PINCache的內部結構比較簡單,最核心的就是2個緩存實現類,這裏先給出一個大概的結構,讓大家可以有個瞭解,下面就來講講詳細的接口。

PINCache接口


PINCache屬性


核心屬性
1.name是PINCache的名字
2.concurrentQueue是一個用來執行異步任務的並行隊列
3.磁盤緩存
4.內存緩存


初始化方法


初始化方法
1.單例對象
2.使用名字初始化
3.使用名字和緩存路徑來初始化


異步方法


異步方法
多數開源緩存框架的方法也就這麼幾個,大多類似。
1.異步按鍵取值,之後執行Block
2.異步按鍵設值,之後執行Block
3.異步按鍵刪值,之後執行Block
4.異步刪除某個時間之後沒有使用的緩存,之後執行Block
5.異步刪除所有緩存,之後執行Block


同步方法


同步方法
這裏的同步方法與異步方法的區別除了方法是否立即返回之外,還有一個區別就是異步方法可以傳入一個Block參數
1.同步按鍵取值
2.同步按鍵設值
3.同步按鍵刪值
4.同步刪除某個時間之後沒有使用的緩存
5.同步刪除所有緩存

PINCache主要是包裝PINDiskCache和PINMemoryCache的功能,具體的功能實現是交給對應的對象去實現

PINDiskCache解析

PINDiskCache涉及到磁盤緩存的具體實現,這裏就不再一一列舉所有的屬性和方法了(具體的內容可以查看PINCache的文檔),主要挑重要的取值方法,設值方法,還有刪除方法來講。


semaphore


PINDiskCache使用semaphore來做線程同步控制的,在寫磁盤緩存的時候給這個文件加鎖,寫完之後解鎖。在讀磁盤緩存的時候也會給這個文件加鎖,讀完之後解鎖。讀寫過程都會加鎖


寫入磁盤緩存


寫磁盤緩存的大概步驟是這樣的,只是講解一些思路,具體的詳細信息需要大家查看源代碼。
1.判斷給的鍵值是否爲空
2.加鎖,保證多線程安全
3.把數據寫入磁盤
4.更新緩存信息(包括但不限於保存磁盤緩存的總容量)
5.判斷現在的磁盤緩存容量是否超過容量限制,若超出,按照緩存時間策略來刪除對應的緩存,沒有超過則不做操作
6.解鎖,讓其他線程可以進入操作


讀取磁盤緩存


讀磁盤緩存相對簡單一些,就是找到文件,然後讀取。
1.判斷給的鍵是否爲空
2.加鎖,保證多線程安全
3.把數據從磁盤讀到內存對象中
4.解鎖,讓其他線程可以進入操作


移除緩存


移除緩存就是文件的刪除操作
1.判斷給的鍵是否爲空
2.加鎖,保證多線程安全
3.把文件從磁盤中刪除
4.解鎖,讓其他線程可以進入操作

PINMemoryCache解析

內存緩存相比磁盤緩存多了一個App收到內存警告或者App進入後臺的時候清理緩存的功能。內存緩存的數據保存在字典裏面。


收到通知,清理內存緩存


1.收到系統內存警告通知,清理內存緩存
2.收到App進入後臺的系統通知,清理內存緩存


內存緩存設值


1.判斷鍵值是否爲空
2.加鎖,保證多線程安全
3.將數據存到緩存池,也就是字典裏面
4.更新緩存對應的數據
5.解鎖
6.判斷內存緩存容量是否超出,超過刪除部分


內存緩存取值


1.判斷鍵值是否爲空
2.加鎖,保證多線程安全
3.從字典裏面取對應值
4.更新緩存對應的數據
5.解鎖


內存緩存刪除

1.取出內存緩存值
2.加鎖
3.更新內存緩存容量
4.刪除內存緩存
5.更新內存緩存對應的數據
6.解鎖

總結

緩存一般�️2個部分組成,一個是內存緩存,一個是磁盤緩存。
1.對於內存緩存來說,一般使用字典來作爲數據的緩存池,配合一個保存每個內存緩存數據的緩存時間的字典,一個保存每個內存緩存數據的緩存容量的字典,一個保存內存緩存總容量的變量。對於增刪改查操作,基本也都是圍繞着字典來的,需要重點注意的就是在這些個操作過程的多線程安全問題,還有同步和異步訪問方法,以及異步方法中的Block參數的循環引用問題。
2.對於磁盤緩存來說,使用文件系統來保存緩存數據,配合設置文件的參數,比如文件的修改日期(訪問一次即修改一次),文件的大小來管理着這個緩存數據。對緩存數據的增刪改查,也就是轉化成爲對文件的讀寫刪除操作。
3.不管是內存緩存還是磁盤緩存,在刪除超過限制容量的緩存的時候總是有一個同樣的策略。有優先刪除緩存最久,最少使用的策略,也有優先刪除,容量最大,最少使用的策略。沒有什麼最好的策略,只有適合你業務產品的策略。
最後感謝PINCache作者給我們提供了一個優秀的緩存開源框架。

本文章來源於項目內存緩存框架研究,旨在介紹PINCache的一些基本內容。具體的細節需要查看源代碼瞭解。
但是如果你覺得我的這篇文章對你有幫助,請在下方點個贊,讓我知道這文章起了作用,謝謝!

參考

http://blog.ibireme.com/2015/10/26/yycache/
https://github.com/pinterest/PINCache

發佈了32 篇原創文章 · 獲贊 3 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章