gpt4 book ai didi

json - 从 TableView 中的 JSON 数据下载可重复使用的单元格或错误的异步图像

转载 作者:行者123 更新时间:2023-11-28 09:24:40 27 4
gpt4 key购买 nike

我有一个从 API 下载 JSON 数据并将其设置在表格 View 单元格中的应用程序。在某些时候,通过在随机单元格图像中向上/向下滚动,在它具有正确的图像之前可能会自行更改几次。文本数据没有任何问题。起初我以为问题是单元格的可重用性,所以我需要在实际设置新图像之前销毁数据。所以我将 TableViewCell 的这种方法添加到 cellForRowAt 路径以在设置单元格之前销毁数据:

func destroyCellData() {

self.newsImageView.image = nil
self.newsTitleLabel.text = nil
self.tagLabel.text = nil
}

然后是设置单元格的实际方法:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

guard let cell = tableView.dequeueReusableCell(withIdentifier: "newscell") as? NewsTableViewCell else {

print("No such cell")
exit(14)
}

cell.loadingImageIndicator.startAnimating()

let data = dataManager.getData()

let dataToInsert = data[indexPath.row]
cell.destroyCellData()
cell.setDataToCell(with: dataToInsert)

return cell
}

方法 setDataToCell 是:

func setDataToCell(newsObject: jsonNews) {

self.newsTitleLabel.text = newsObject.title
self.tagLabel.text = newsObject.tag

let url = newsObject.imageURL
self.newsImageView.loadImageUsingCacheWithURLString(url, placeholder: UIImage(named: "ViewPlaceholder"), indicator: loadingImageIndicator)

}

最后我在单元格中异步加载图像:

let imageCache = NSCache<NSString, UIImage>()

extension UIImageView {

func loadImageUsingCacheWithURLString(_ URLString: String, placeholder: UIImage?, indicator: UIActivityIndicatorView? = nil) {

self.image = nil

if let cachedImage = imageCache.object(forKey: NSString(string: URLString)) {

self.image = cachedImage
indicator?.stopAnimating()
return

}

guard let encodedString = URLString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {

print("Error Loading URL")
return
}

if let url = URL(string: encodedString) {

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

if error != nil {

print("ERROR LOADING IMAGES FROM URL: \(String(describing: error))")

OperationManager.UI {

self.image = placeholder
indicator?.stopAnimating()
}

return
}

if let data = data {

if let downloadedImage = UIImage(data: data) {

print(URLString)
imageCache.setObject(downloadedImage, forKey: NSString(string: URLString))

OperationManager.UI {

self.image = downloadedImage
indicator?.stopAnimating()
}
}
}
}).resume()
}
}

所以我的问题是 - 问题出在我下载和设置图像的方法上,还是出在单元的可重用性上?如果可能的话,给我一个更合适的方法来将图像设置为单元格的提示。提前致谢

最佳答案

如果没有您的代码,我怀疑您的问题可能与可重用单元格和异步图像下载有关。这样一来,当您重新加载单元格时,它会启动一个数据任务来下载图像,如果第二个任务开始下载不同的图像,则第一个任务不会发生任何事情。

例如,假设您的第一张图片为 100MB,可重复使用单元格的第二张图片为 1KB。希望 1KB 下载速度更快。这是流程

  1. 带有 image1 的称重传感器
  2. 开始下载image1
  3. 带有 image2 的称重传感器
  4. 开始下载image2
  5. 完成image2的下载
  6. 将单元格图像设置为image2
  7. 完成下载 image1
  8. 将单元格图像设置为image1

由于image2已经设置好,image1的数据下载任务已经完成,cell在显示image2后会更新显示image1,从而显示错误的图片。

要解决您的问题,您需要以某种方式取消第一个操作,或者更确切地说,如果不再显示该数据,则不更新 ImageView 。有很多方法可以做到这一点。一种解决方案是在您的单元格上创建图像 url 的属性,并在下载完成后确认其正确的 url,如果正确,则更新 ImageView 。

func setDataToCell(newsObject: jsonNews) {
// Your other code
self.imageURL = newsObject.imageURL
}

// loadImageUsingCacheWithURLString
if let downloadedImage = UIImage(data: data) {

print(URLString)
imageCache.setObject(downloadedImage, forKey: NSString(string: URLString))

OperationManager.UI {
if url.absoluteString == self.imageURL {
self.image = downloadedImage
indicator?.stopAnimating()
}
}
}

注意:没有测试任何这段代码,而是直接从我的脑海中写出来的。它可能有错误。

综上所述,我建议使用第三方图像缓存系统,如 AlamofireImage或人们评论过的其他人之一。

关于json - 从 TableView 中的 JSON 数据下载可重复使用的单元格或错误的异步图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46207630/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com