缓存图像时为零

Nil while caching images

我已经能够解决缓存图像的问题以提高我的应用程序的滚动性能。然而,当它试图将它添加到 cache 时,却发现 nil。另外,如何为加载失败或不可用的图像添加占位符图像?

let imageCache = NSCache<NSString, UIImage>()

    extension UIImageView {
    
        func downloadImage(from imgURL: String) -> URLSessionDataTask? {
            guard let url = URL(string: imgURL) else { return nil }
    
            // set initial image to nil so it doesn't use the image from a reused cell
            image = nil
    
            // check if the image is already in the cache
            if let imageToCache = imageCache.object(forKey: imgURL as NSString) {
                self.image = imageToCache
                return nil
            }
    
            // download the image asynchronously
            let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
                if let err = error {
                    print(err)
                    return
                }
    
                DispatchQueue.main.async {
                    // create UIImage
                    let imageToCache = UIImage(data: data!)
                    // add image to cache
                    imageCache.setObject(imageToCache!, forKey: imgURL as NSString)
                    self.image = imageToCache
                }
            }
            task.resume()
            return task
        }
    }

一些观察:

  1. 只需提供 placeholder 作为函数的参数并使用它代替 nil 来初始化 image.

  2. 检查缓存后执行此操作(因为如果您在缓存中找到所需图像,则使用占位符毫无意义)。

  3. 避免使用 ! 强制展开运算符。

  4. 检查 UIImage(data:)guard 语句中(在会话队列中,而不是在主线程中)找到图像。

因此:

let imageCache = NSCache<NSString, UIImage>()

extension UIImageView {
    func downloadImage(from imgURL: String, placeholder: UIImage? = nil) -> URLSessionDataTask? {
        guard let url = URL(string: imgURL) else { return nil }
        
        // check if the image is already in the cache
        if let imageToCache = imageCache.object(forKey: imgURL as NSString) {
            image = imageToCache
            return nil
        }
        
        // set initial image to placeholder so it doesn't use the image from a reused cell
        image = placeholder
        
        // download the image asynchronously
        let task = URLSession.shared.dataTask(with: url) { data, _, error in
            guard 
                let data = data, 
                error == nil,
                let imageToCache = UIImage(data: data)
            else {
                print(error ?? URLError(.badServerResponse))
                return
            }
            
            imageCache.setObject(imageToCache, forKey: imgURL as NSString)

            DispatchQueue.main.async {
                self.image = imageToCache
            }
        }
        task.resume()
        return task
    }
}