【问题标题】:Images cached are flickering缓存的图像闪烁
【发布时间】:2019-08-01 08:19:32
【问题描述】:

我正在从 Cloud Storage 下载图片,它们在我的整个应用程序中使用。我已经缓存了它们,但是当我的表格滚动或重新加载时,我仍然看到一些闪烁。

这是我尝试过的:

我的缓存代码:

import UIKit

class ImageService {

    static let cache = NSCache<NSString, UIImage>()

    static func downloadImage(withURL url:URL, completion: @escaping (_ image:UIImage?)->()) {
        let dataTask = URLSession.shared.dataTask(with: url) { data, responseURL, error in
            var downloadedImage: UIImage?

            downloadedImage = nil

            if let data = data {
                downloadedImage = UIImage(data: data)
            }

            if downloadedImage != nil {
                cache.setObject(downloadedImage!, forKey: url.absoluteString as NSString)
            }

            DispatchQueue.main.async {
                completion(downloadedImage)
            }
        }

        dataTask.resume()
    }

    static func getImage(withURL url:URL, completion: @escaping (_ image:UIImage?)->()) {
        if let image = cache.object(forKey: url.absoluteString as NSString) {
            print("IMAGE IS LOADED FROM CACHE!!!!")
            DispatchQueue.main.async {
                completion(image)
            }
        } else {
            print("IMAGE IS LOADED FROM DOWNLOAD!!!!")
            downloadImage(withURL: url, completion: completion)
        }
    }
}

这是我的一张表中的一个示例:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    cell.imageView.image = nil

    let storage = Storage.storage()
    let storageRef = storage.reference()
    let imageRef = storageRef.child(String(format: "images/%@.jpg", id))

    imageRef.downloadURL { (URL, error) in
        if error == nil {
            DispatchQueue.main.async {
                ImageService.getImage(withURL: URL!, completion: { image in
                   cell.imageView.image = image
              })
           }
        } else {
          cell.imageView.image = UIImage (named: "placeholder")
        }
    }
}

我看到,当我第一次加载我的应用程序时,会下载图像,然后再从缓存中加载它们。但我仍然看到它们闪烁。有什么建议可以更新上述内容以缓存到内存和磁盘或解决闪烁问题?

解决方法:

我正在使用 FirebaseUI,它有一个修改版本的 SDWebImage 来缓存基于存储参考。

【问题讨论】:

  • let imageRef = storageRef.child(String(format: "images/%@.jpg", id))中的id是什么?
  • @ElTomato 这是为每个用户创建的唯一 ID。
  • 看看你的委托函数,你的图像可能会在每次有 tableView.reload() 时重新下载,这会导致闪烁。您是否正在单步执行该代码以查看是否发生了这种情况?
  • @Jay 是的,他们正在从缓存中加载。
  • 我问他们是否在 tableView.reloadData() 上重新下载,您回答 yes 并添加了 从缓存加载。那么他们是否每次都下载 他们是否每次都从缓存中加载其他东西?我问他们是否每次刷新 tableView 时都在下载,它只是会闪烁 - 你还有其他一些逻辑问题导致了这种情况。

标签: swift firebase uitableview caching firebase-storage


【解决方案1】:

您应该从UITableView 委托方法中删除以下几行。

let storage = Storage.storage()
let storageRef = storage.reference()

并将它们设为类变量。

【讨论】:

  • 当我的表重新加载时仍然看到闪烁。
  • 把第 3 行 (let imageRef = storageRef.child(String(format: "images/%@.jpg", id))) 也拿出来。如果这不起作用,那是你没有提到的其他事情。
  • 不确定我是否可以这样做,因为在大多数视图控制器中,id 在 indexPath.row 中都是唯一的。
【解决方案2】:

TBH 我不知道这是否可行。但我有同样的问题,你必须将 cell.imageview 设置为 nil

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// cell.imageView.image = nil (remove)

let storage = Storage.storage()
let storageRef = storage.reference()
let imageRef = storageRef.child(String(format: "images/%@.jpg", id))

imageRef.downloadURL { (URL, error) in
    if error == nil {
        DispatchQueue.main.async {

            ImageService.getImage(withURL: URL!, completion: { image in
               cell.imageView.image = nil //add
               cell.imageView.image = image
          })
       }
    } else {
      cell.imageView.image = nil // Add
      cell.imageView.image = UIImage (named: "placeholder")
    }
}
}

【讨论】:

    猜你喜欢
    • 2010-10-29
    • 2012-08-22
    • 2015-04-25
    • 2012-05-13
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    相关资源
    最近更新 更多