美文网首页
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