OS開發中或多或少都會使用到Cache來減少網路請求,在網路上也有很多使用Objective-c開發的Cache框架,而Swift開發的Cache框架相對來說就要少一些,所以我就用Swift 5開發了一款Cache庫-SwiftlyCache
(https://github.com/hlc0000/SwiftlyCache)
- 支援所有遵守
Codable
協議的資料型別 - 支援
LRU
淘汰演算法 - 當收到記憶體警告或者App進入後臺時,記憶體快取可以配置為自動清空或者手動清空
- 支援使用
Subscript
,使讀寫資料更加方便 - 提供了
MultiCacheGennerator
、MemoryCacheGenerator
、DiskCacheGenerator
用於支援for..in
、compactMap
、map
、filter
等方法
CacheAware:提供了一些基本介面的協議,MultiCache,MemoryCache,DiskCache等都遵守該協議.
MultiCache:多重快取,呼叫MemoryCache以及DiskCache相關方法.
MemoryCache:負責處理容量小,相對高速的記憶體快取,執行緒安全,支援非同步操作,支援自動和手動清理快取功能.
MemoryStorage:MemoryCache使用的雙向連結串列類.
LinkedNode:雙向連結串列節點類.
DiskCache:負責處理容量大,相對低速的磁碟快取,執行緒安全,支援非同步操作,自動和手動清理快取功能.
DiskStorage:DiskCache內部實現類.
DiskStorageItem:用於載入磁碟快取資料使用的.
SwiftlyCache支援使用Subscript,讀寫更加方便.
SwiftlyCache提供了MultiCacheGenerator、MemoryCacheGenerator、DiskCacheGenerator用於支援for... in、compactMap、 map、filter等一系列方法
CocoaPods:
1.在Podfile中新增pod SwiftlyCache
2.執行pod install
或者pod update
3.匯入 SwiftlyCache
手動匯入:
1.下載SwiftlyCache
資料夾內所有內容
2.將SwiftlyCache
內的原始檔新增到你的工程
屬性的使用:
MemoryCache
可供使用的屬性:
設定最大的記憶體快取容量(0為不限制)
public var totalCostLimit:vm_size_t = 0
設定最大的記憶體快取數量
public var totalCountLimit:vm_size_t = 0
系統記憶體警告是否刪除所有記憶體資料,預設為true
public var autoRemoveAllObjectWhenMemoryWarning =true
進入後臺是否刪除所有記憶體資料,預設為true
public var autoRemoveAllObjectWhenEnterBackground =true
DiskCache可供使用的屬性:
設定最大的磁碟快取容量(0為不限制)
public var maxSize:vm_size_t = 0
設定最大的磁碟快取數量
public var maxCountLimit:vm_size_t = 0
快取的過期時間(預設是一週)
public var maxCachePeriodInSecond:TimeInterval = 60 * 60 * 24 * 7
自動檢查時間設定(預設為120秒)
自動檢查磁碟快取是否達到限制,如果達到限制,則自動丟棄部分資料(快取最大容量限制、快取最大個數限制、資料是否過期)
public var autoInterval:TimeInterval = 120
介面的使用:
MultiCache
和MemoryCache
,DiskCache
中的設定快取、獲取快取、根據key
查詢是否存在對應的快取資料、移除全部快取資料、根據key
移除對應的快取資料都是遵守CacheAware
協議的
設定快取物件:(Value
為所有遵守Codable
協議的資料型別)
public funcset(forKey key: String, value: Value?, cost: vm_size_t = 0)->Bool
public funcset(forKey key:String,value:Value?,cost:vm_size_t = 0,completionHandler:@escaping((_ key:String,_ finished:Bool) -> Void))
可以通過Subscript
的形勢設定快取key
、Value
cache["key"] = Value
獲取快取物件
public func object(forKey key: String) -> Value?public func object(forKey key:String,completionHandler:@escaping((_ key:String,_ value:Value?) -> Void))
也可以通過Subscript
的方式獲取對應的快取物件
let object = cache["key"]
根據給定的key
查詢快取中是否存在對應的Value
public func isExistsObjectForKey(forKey key: String) -> Bool
public func isExistsObjectForKey(forKey key:String,completionHandler:@escaping((_ key:String,_ contain:Bool) -> Void))
根據key
移除快取中對應的value
public func removeObject(forKey key: String)
public func removeObject(forKey key: String, completionHandler: @escaping (() -> Void))
移除所有快取
public func removeAll()public func removeAll(completionHandler:@escaping(() -> Void)
也可以通過for ... in
、compactMap
、 map
、filter
等方式獲取到對應的快取資料
public func makeIterator() -> MultiCacheGenerator
let iterator = cache.makeIterator()
while let result = iterator.next(){}
let flatMapResult = cache.compactMap{$0}
print("flatMapResult:\(flatMapResult)")
let filterResult = cache.filter{(key,object) -> Bool in return key =="shirley2"}
print("filterResult:\(filterResult)")
cache.forEach(print($0) )
let values = cache.map{return$0}
print("value:\(value)")
for(key,object) in cache{
print("key:\(key),object:\(object)")
}
MultiCache
與MemoryCache
所有的可供使用的介面就介紹完了,DiskCache
除了上述所有介面之外還有以下幾個:
移除所有過期資料
public func removeAllExpired()->Bool{}
獲取磁碟快取總個數
public func getTotalItemCount()->Int}
public func getTotalItemCount(completionHandler:@escaping((_ count:Int)->Void)){}
獲取磁碟快取總佔用容量
public func getTotalItemSize()->Int32{}
public func getTotalItemSize(completionHandler:@escaping((_ size:Int32)->Void)){}
之前也看過一些用Objective-c開發的Cache框架,比如PINCache
,YYCache
等,也基本瞭解了他們的一些優缺點,所以在SwiftlyCache
中也儘量融合了他們的一些優點.
單執行緒下的MemoryCache
效能測試(150000次)
PINMemoryCache
寫入資料時採用三個字典的方式分別記錄快取物件、快取時間、快取容量,在每次寫入資料時都需要依次對三個字典進行寫入操作.
YYMemoryCache
和SwiftlyCache
在每次寫入資料的時候最多隻需要對字典進行一次寫入操作.
在每次快取資料完成之後,都需要丟棄超出TotalCount
和TotalCost
的資料,PINMemoryCache
在淘汰時都需要對Date
字典重新進行排序,然後再丟棄掉最老的資料.
而YYCache
和SwiftlyCache
則需要每次從連結串列的最後開始移除,YYCache
的cost
淘汰是非同步執行緒中進行的,而SwiftlyCache
則是在當前執行緒中進行(每一次設定快取資料完成後都會對TotalCost
進行判斷,可丟棄資料很少,如果使用非同步執行緒的開銷蠻大的).
單執行緒下的DiskCache
效能測試(1000次,左側資料為10k,右側資料為100k)
PINDiskCache
使用檔案快取資料,設定檔案引數,檔案的大小來管理快取資料,對快取資料的增刪改查也是轉化為對檔案的讀寫刪除操作.
YYDiskCache
和SwiftlyCache
中DiskCache
都是使用SQLite
和檔案結合的方式進行資料快取,可以更好得擴充套件後設資料,實現LRU
淘汰演算法,當快取資料超過20k,將後設資料寫入資料庫,value
寫在檔案中.
本作品採用《CC 協議》,轉載必須註明作者和本文連結