第二次读Kingfisher网络图片缓存库的思考与感觉

协议那个先放一放,咱们先来继续完善本身的缓存网络图片库,Kingfisher 3.0已经稍微有点成熟了,有不少东西一时半会看不懂,可是咱们先来本身实现一下,而后对比区别和学习。swift

上一次已经写了一个分类用于全部控件一行代码加载图片,接下来咱们来作一个缓存,可让它不每次都去加载,这样会速度很快节省资源并且不用考虑网络因素。缓存

咱们在每次加载的时候 先去判断缓存的内存里有没有已经存入该图片,若是存入了就直接拿出来加载,若是没有存入就再进行下面加载的代码,这样先不考虑硬盘存储,先作一个最简单的。网络

说到缓存类,那么咱们必定会要用到单例(虽然我没看到Kingfisher的缓存类 用单例,可是后面会边研究边解谜,先按本身的思路来,不要凡事都靠别人的代码粘贴):ide

import Foundation
//这里不写:继承类,它默认会继承什么呢? Object?
class ImageCache {
    //单例
    static let shared = ImageCache()
}

有了单例之后呢,咱们就能够给一个字典,来把图片的url当key,图片当value来作一个内存的缓存。由于是单例因此共享一个对象,无论在哪里操做都是用的这个储存的。虽然到后面能够把字典换成 NSCache 可是咱们仍是一步步来吧。学习

有的语法可能不对 后期优化,缓存到内存功能已经实现:测试

//这里不写:继承类,它默认会继承什么呢? Object?
class ImageCache {
    //声明及初始化
    var memoryDic:NSMutableDictionary? = [:]
    //单例
    static let shared = ImageCache()
    //存储图片
    func storeImage(url:URL,image:UIImage?) -> Void {
        let urlStr = "\(url)"
        memoryDic?.setValue(image, forKey:urlStr)
    }
    //取图片
    func imageForKey(url:URL) ->UIImage? {
        let urlStr = "\(url)"
        if memoryDic?.allValues.count != 0 && memoryDic?.allValues.count != nil {
            let image:UIImage = memoryDic!.object(forKey: urlStr) as! UIImage
            return image
        }
        return nil
    }
 }

分类:优化

import Foundation
import UIKit
/// typealias用来为已存在的类型从新定义名称的。
typealias ImageView = UIImageView
extension ImageView {
    func sfsc_setImage(url:URL?) -> Void {
        //------- 这部分代码,每一个须要网络图片的都会用到,因此提取出来 ---------
        /* guard let语法:guard let 判断以后 守护 必定有值 若是没有值 在guard let 的{} 里 直接返回。
          若是须要守护多个值直接在后面跟 逗号 分割开来。
         
         */
        guard let url = url else {
            return
        }
        //代码执行至此 url 必定有值!!
        if (ImageCache.shared.imageForKey(url: url) != nil) {
            self.image = ImageCache.shared.imageForKey(url: url)
        }
        
        //转为data类型
        let data : NSData! = NSData(contentsOf: url)
        //判断data不为空,这里是由于swift对类型要求很严,若是未空的话,会崩溃
        if data != nil {
            //赋值图片
            self.image = UIImage.init(data: data as Data, scale: 1)
            ImageCache.shared.storeImage(url: url, image: self.image!)
        }else{
            // 不然就赋值默认图片
            self.image = UIImage.init(named: "005")
        }
    }
}

测试一下 第一个页面类里写:url

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell:CollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! CollectionViewCell

        // 初始化url图片
        let url:URL = URL.init(string:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1572933973277&di=dfcdb7e4aa6339a22ca5e40270987790&imgtype=0&src=http%3A%2F%2Fpic44.nipic.com%2F20140723%2F18505720_094503373000_2.jpg")!
        cell.cellImageView.sfsc_setImage(url: url)
        return cell
    }

第二个类里写:code

import UIKit

class TestViewController: UIViewController {
    @IBOutlet weak var testImageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //这里测试就用一个上个页面缓存过的URL
        testImageView.backgroundColor = UIColor.cyan
        let url:URL = URL.init(string:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1572933973277&di=dfcdb7e4aa6339a22ca5e40270987790&imgtype=0&src=http%3A%2F%2Fpic44.nipic.com%2F20140723%2F18505720_094503373000_2.jpg")!
        testImageView.image = ImageCache.shared.imageForKey(url: url)
        // Do any additional setup after loading the view.
    }

若是能显示出来就是缓存到内存成功!耶~对象

相关文章
相关标签/搜索