美文网首页
Kingfisher源码之Cache

Kingfisher源码之Cache

作者: Mannyao | 来源:发表于2020-08-21 17:24 被阅读0次

Kingfisher的的图片缓存有内存缓存和磁盘缓存两种,都是有ImageCache类负责;

ImageCache的功能:

  1. 缓存图片
  2. 检索图片
  3. 清理图片

1.缓存图片

缓存图片分为下面两种方式:

  • 内存缓存
  • 磁盘缓存
内存缓存

内存缓存是由NSCache完成的,具体实现设计是通过MemoryStroage枚举中的Backend 类实现;下面介绍内存缓存的Backend
Backend中两个重要的类型:

  • StorageObject 储存的实体类
  • Config 结构体可以理解储存的配置
    StorageObject 指定了一个泛型类型T,这里一般用的是Image,还有缓存key以及StorageExpiration对象,一个过期的枚举。
    Config 指定NSCache的最大字节数,一个StorageExpiration对象指定什么时候过期默认是(300s)过期,清理内存缓存的时间默认是(120s)。
    MemoryStroage中的Backend通过config初始化,初始化了一个NSCache对象storage, 和一个定时器按照config中配置的时间定时清理过期的缓存;
    提供的方法肯定有 store存储,valueforKey根据key来获取储存的实体。remove方法等方法;
磁盘缓存

磁盘缓存是通过DiskStorage枚举中的Backend类实现,跟磁盘缓存同样的结构。
磁盘缓存中有个两个中重要类型:

  • FileMeta 类
  • Config 结构体
    FileMeta类中包括存储的url,上次访问的时间,过期时间,文件大小等;
    Config结构体包括过期时间默认是7days, name, 文件操作fileManager, pathExtenstion 路径扩展等。文件路径directory
    DiskStorage中的Backend指定的泛型T是遵守DataTransFormable;这里有点面向协议的味道了,Kingfisher中是Data遵守了该协议; Backend同样通过Config来初始化。然后就是通过congfig中的fileManager来进行一系列的文件存储和删除操作;在检索的时候用的了FileMeta通过fileMeta对象来计算文件是否过期,以及延长过期时间。还有一点缓存文件的名字是以文件的md5来命名的。

2.检索图片

从初始化方法中可以看出ImageCache 连接MemoryStroage和DiskStorage。

  public init(memoryStorage: MemoryStorage.Backend<Image>,
                diskStorage: DiskStorage.Backend<Data>) {
        self.memoryStorage = memoryStorage
        self.diskStorage = diskStorage
        let ioQueueName = "com.onevcat.Kingfisher.ImageCache.ioQueue.\(UUID().uuidString)"
        ioQueue = DispatchQueue(label: ioQueueName)
        
        let notifications: [(Notification.Name, Selector)]
        notifications = [
            (UIApplication.didReceiveMemoryWarningNotification, #selector(clearMemoryCache)),
            (UIApplication.willTerminateNotification, #selector(cleanExpiredDiskCache)),
            (UIApplication.didEnterBackgroundNotification, #selector(backgroundCleanExpiredDiskCache))
        ]
        notifications.forEach {
            NotificationCenter.default.addObserver(self, selector: $0.1, name: $0.0, object: nil)
        }
    }

1.先从内存缓存中检索,再从磁盘中找,尾随闭包是Result<ImageCacheResult, KingfisherError>

public enum ImageCacheResult {
    case disk(Image)
    case memory(Image)
    case none
    public var image: Image? {
        switch self {
        case .disk(let image): return image
        case .memory(let image): return image
        case .none: return nil
        }
    }
    public var cacheType: CacheType {
        switch self {
        case .disk: return .disk
        case .memory: return .memory
        case .none: return .none
        }
    }
}

3.清理图片

上面解释过情况内存缓存默认有一个120s的定时器,除了这个ImageCache监听了系统的三个通知,从上面ImageCache初始化中可以看出:在收到系统内存警告的时候清理内存缓存,在进入后台,以及终止程序的时候清理过期的磁盘缓存。

相关文章

网友评论

      本文标题:Kingfisher源码之Cache

      本文链接:https://www.haomeiwen.com/subject/gpmujktx.html