协议那个先放一放,咱们先来继续完善本身的缓存网络图片库,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. }
若是能显示出来就是缓存到内存成功!耶~对象