第二次讀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.
    }

若是能顯示出來就是緩存到內存成功!耶~對象

相關文章
相關標籤/搜索