協議那個先放一放,咱們先來繼續完善本身的緩存網絡圖片庫,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. }
若是能顯示出來就是緩存到內存成功!耶~對象