- base NSCache store image
- base a serialize queue async to access Disk
- CachePath: default cache/cacheName
init method
parameters
- name: CacheName
- path: Cache path
- diskCachePathClosure: Cache path append closure,
store and remove Image
- store Image: sync add image to NSCache and async write imageData to disk if necessary
- remove Image: sync remove image to NSCache and async remove imageData to disk if necessary
retrieve Image
sync retrieve
retrieveImageInMemoryCache:forKey:options:
retrieveImageInDiskCache:forKey:options:
async retrieve
retrieveImageforKey:options:completionHandler:
clear
auto clear expired Files
when UIApplicationWillTerminate triger cleanExpiredDiskCache
when UIApplicationDidEnterBackground triger backgroundCleanExpiredDiskCache
when UIApplicationDidReceiveMemoryWarning triger clearMemoryCache
manauage clear expired Files
- clearDiskCache
- clearMemoryCache
clearMemoryCache
: just remove Memory Cache
cleanExpiredDiskCache
: 清空过期文件
clearDiskCache
: 清空所有缓存文件
cleanExpiredDiskCache
代码片段:
// description remove Expired files
...
if currentDiskCachaSize < maxDiskCacheSize {
sort disk Cache files by descending
while currentDiskCachaSize > maxDiskCacheSize / 2 {
remove the bigges file
}
}
这个地方就很有意思, 作者在清除掉所有已过期文件后,会对当前缓存大小进行再次检测,如果缓存大小超过预期的话,对缓存文件进行降序排序,并不断删除最大的那个文件,直到
当前缓存大小小于预期缓存的1/2。 首先 cleanExpiredDiskCache
是能自动触发的,这样的操作能保证缓存文件一直小于预期值,不用用户手动操作,一旦达到临界值直接将缓存减少为预期值的1/2之一,这样可以避免重复触发这个机制, 同时从最大文件开始删除,可以理解为一种删除策略,这样做的目的删除文件同时,尽量减少对用户使用的影响。这种策略不一定是最好的,但应该说是有效的。
@objc public func backgroundCleanExpiredDiskCache() {
// if 'sharedApplication()' is unavailable, then return
guard let sharedApplication = Kingfisher<UIApplication>.shared else { return }
func endBackgroundTask(_ task: inout UIBackgroundTaskIdentifier) {
sharedApplication.endBackgroundTask(task)
task = UIBackgroundTaskInvalid
}
var backgroundTask: UIBackgroundTaskIdentifier!
backgroundTask = sharedApplication.beginBackgroundTask {
endBackgroundTask(&backgroundTask!)
}
cleanExpiredDiskCache {
endBackgroundTask(&backgroundTask!)
}
}
backgroundCleanExpiredDiskCache
特殊性在于程序在后台不能一直执行,所以必须设置endBackgroundTask
来结束线程。
travel image
通过imageKey 检索文件,通常imageKey由URL和其他相关实例id拼接而成
notification
post notification
KingfisherDidCleanDiskCache:
observer notification
UIApplicationDidReceiveMemoryWarning -> clearMemoryCache
UIApplicationWillTerminate -> cleanExpiredDiskCache
UIApplicationDidEnterBackground -> backgroundCleanExpiredDiskCache
技巧解析
/*
open func retrieveImage(forKey key: String,
options: KingfisherOptionsInfo?,
completionHandler: ((Image?, CacheType) -> Void)?) -> RetrieveImageDiskTask?
*/
...
var sSelf: ImageCache! = self
block = DispatchWorkItem(block: {
// Begin to load image from disk
if let image = sSelf.retrieveImageInDiskCache(forKey: key, options: options) {
if options.backgroundDecode {
sSelf.processQueue.async {
let result = image.kf.decoded
sSelf.store(result,
forKey: key,
processorIdentifier: options.processor.identifier,
cacheSerializer: options.cacheSerializer,
toDisk: false,
completionHandler: nil)
options.callbackDispatchQueue.safeAsync {
completionHandler(imageModifier.modify(result), .memory)
sSelf = nil
}
}
} else {
...
}
- 相对于引用weakSelf,再转StrongSelf这种操作,这里延长了self的生命周期, weakSelf在回调完成的时候,很有可能是nil,那么接下来的操作无法完成,这里进行强引用保证其不为空,确保接下来的操作能够顺利完成
- 使用隐式解析,明确告诉编译器,由程序员保证其值的可选性,可以使代码变得简洁,但是不建议大范围的使用,在某些特定的场景还是比较合适的。
网友评论