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

我正在swift 3.0中的一个项目woking我在哪里caching服务器的响应通过使用NSCache作为填充它们在UITableView。 然而,由于某种原因,我只看到几个图像加载时,第一次加载的应用程序,但如果如果我滚动,回来我看到的一切(检索服务器的响应结束我重新加载我的tableview,但似乎不是这种情况)。 我不知道我在这里错过了什么,代码如下,以显示如何caching图像。

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() } } } 

这里的图像下载并存储在caching中就好了。 问题在于tableview单元格的更新。

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

由于滚动,tableview再次调用“cellForRowatIndexpath”,它将在滚动时更新显示下载图像的单元格。

如果您仍然希望使用扩展名,我build议您添加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() } } 

我认为这将是一个更好的方法使用子类化,而不是扩展(从Jageen的评论帮助,因为我们不能包含扩展内存储的属性,所以我们使用封装的想法)

 let imageCache = NSCache<AnyObject, AnyObject>() class CustomImageView: UIImageView { var imageUrlString: String? func loadImageUsingUrlString(_ urlString: String) { let url = URL(string: urlString) imageUrlString = urlString image = nil if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage { self.image = imageFromCache return } URLSession.shared.dataTask(with: url!) { (data, response, error) in if error != nil { print(error!) return } DispatchQueue.main.async { let imageToCache = UIImage(data: data!) if self.imageUrlString == urlString { self.image = imageToCache } imageCache.setObject(imageToCache!, forKey: urlString as AnyObject) } }.resume() } } 

– 将此子类用作屏幕上显示的imageViews的types