Update table cell image asynchronously

匆匆过客 提交于 2019-12-12 17:15:08

问题


Im downloading the image link from a json and then creating the image once the table view start creating its cells:

 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
}

And this works fine, but the table view becomes really slow, not at rendering but at scrolling. I keep checking the RAM and CPU and both are really low but my network use keeps rising BUT the images are already on the cell so it means its already done. (For this test im calling the JSON for only 2 movies, so 2 images)

Before i started doing this my total download was about 200kb (with images), now its getting over 2MB before i stop the project.

What im doing wrong?


回答1:


You'll probably want to designate a separate queue for background activities. In this instance, your heavy network task is in:

NSData(contentsOf: url as URL)

This is what is "freezing" the UI. The best solution would be to define something like DispatchQueue.background and perform the network calls there, while then later performing the UI tasks back on the main thread so as not to lock up your display:

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

Let me know if this makes sense.



来源:https://stackoverflow.com/questions/41814333/update-table-cell-image-asynchronously

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!