【问题标题】:Update table cell image asynchronously异步更新表格单元格图像
【发布时间】:2017-06-08 10:25:06
【问题描述】:

我从 json 下载图像链接,然后在表格视图开始创建其单元格后创建图像:

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

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCellController

            DispatchQueue.main.async(execute: { () -> Void in

                if let url = NSURL(string: self.movies[indexPath.row].image) 
                {

                    if let data = NSData(contentsOf: url as URL)
                    {
                        let imageAux = UIImage((data: data as Data))
                        cell.movieImage.image = imageAux
                        self.tableView.reloadData()

                    }
                }
            })

        cell.name = self.movies[indexPath.row].name
        cell.date = self.movies[indexPath.row].date
        return cell
}

这很好用,但是表格视图变得非常慢,不是在渲染时而是在滚动时。我一直在检查 RAM 和 CPU,两者都非常低,但我的网络使用量一直在上升,但是图像已经在单元格上,所以这意味着它已经完成了。 (对于这个测试,我只为 2 部电影调用 JSON,所以 2 张图片)

在我开始这样做之前,我的总下载量约为 200kb(带图像),现在在我停止项目之前已经超过 2MB。

我做错了什么?

【问题讨论】:

    标签: ios json swift asynchronous tableviewcell


    【解决方案1】:

    您可能希望为后台活动指定一个单独的队列。在这种情况下,您繁重的网络任务在:

    NSData(contentsOf: url as URL)

    这就是“冻结”用户界面的原因。最好的解决方案是定义 DispatchQueue.background 之类的东西并在那里执行网络调用,然后在主线程上执行 UI 任务,以免锁定您的显示:

    DispatchQueue.background.async(execute: { () -> Void in
        if let url = NSURL(string: self.movies[indexPath.row].image)  {
            //Do this network stuff on the background thread
            if let data = NSData(contentsOf: url as URL) {
                let imageAux = UIImage(data: data as Data)
                //Switch back to the main thread to do the UI stuff
                DispatchQueue.main.async(execute: { () -> Void in
                    cell.movieImage.image = imageAux
                })
            }
        }
    })
    

    让我知道这是否有意义。

    【讨论】:

    • 非常感谢!另一个问题是我不需要重新加载表格,图像下载了几十次(很明显,但我一开始没有看到)。非常感谢迈克尔!
    • Michael Fourre 我知道这不是问题,但我意识到我有问题,因为我每次向上或向下滚动时都使用 dequeueReusableCell 单元格会再次下载图像,我该如何避免这种情况?谢谢!
    • 我会将@Adrian 的图像缓存到NSCache 文档中。它很容易使用。如果您发布另一个问题,我可以添加我的 UIImage 缓存代码的 sn-p 作为示例
    • 是的,这就是解决方案。我还有一个小问题,但一切都很好。感谢您的帮助,迈克尔
    猜你喜欢
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多