一尘不染

首次加载时,NSCache不适用于所有图像

swift

我正在swift
3.0中的一个项目中醒来,在该项目中,我使用NSCache将服务器的响应缓存在UITableView中,从而缓存了这些响应。但是由于某种原因,当我第一次加载该应用程序时,我只会看到很少的图像加载,但是如果我滚动并返回时,我会看到所有内容(从服务器检索响应结束时,我也重新加载了tableview,但是似乎并非如此)。我不确定我到底在这里缺少什么,下面的代码展示了我如何缓存图像。

let imageCache = NSCache<AnyObject, AnyObject>()
var imageURLString : String?

extension UIImageView {


    public func imageFromServerURL(urlString: String) {
        imageURLString = urlString

        if let url = URL(string: urlString) {

            image = nil


            if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage {

                self.image = imageFromCache

                return
            }

            URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in

                if error != nil{
                    print(error as Any)


                    return
                }

                DispatchQueue.main.async(execute: {

                    if let imgaeToCache = UIImage(data: data!){

                        if imageURLString == urlString {
                            self.image = imgaeToCache
                        }

                        imageCache.setObject(imgaeToCache, forKey: urlString as AnyObject)// calls when scrolling
                    }
                })
            }) .resume()
        }
    }
}

阅读 278

收藏
2020-07-07

共1个答案

一尘不染

在这里下载图像并将其存储在缓存中就可以了。问题在于更新tableview单元格。

当表格视图将单元格加载到表格上时,图像尚未下载。但是,一旦下载了图像,我们就必须有选择地更新单元格,以便立即显示图像。

由于正在滚动,因此表视图再次调用“ cellForRowatIndexpath”,这将更新滚动时显示已下载图像的单元格。

如果您仍然希望使用扩展名,建议您添加tableView和indexpath作为参数,以便我们可以调用重新加载特定行并立即更新视图。

我已经更新了表重载代码和扩展中定义的函数的结构。让我知道事情的后续。

let imageCache = NSCache<AnyObject, AnyObject>()
var imageURLString : String?

extension UIImageView {


public func imageFromServerURL(urlString: String, tableView : UITableView, indexpath : IndexPath)) {
    imageURLString = urlString

    if let url = URL(string: urlString) {

        image = nil


        if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage {

            self.image = imageFromCache

            return
        }

        URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in

            if error != nil{
                print(error as Any)


                return
            }

            DispatchQueue.main.async(execute: {

                if let imgaeToCache = UIImage(data: data!){

                    if imageURLString == urlString {
                        self.image = imgaeToCache
                    }

                    imageCache.setObject(imgaeToCache, forKey: urlString as AnyObject)// calls when scrolling

    tableView.reloadRows(at: [indexpath], with: .automatic)

                }
            })
        }) .resume()
    }
}
2020-07-07