异步更新 table 细胞图像
Update table cell image asynchronously
我正在从 json 下载图像 link,然后在 table 视图开始创建其单元格后创建图像:
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
}
这工作正常,但 table 视图变得非常慢,不是在渲染时而是在滚动时。我一直在检查 RAM 和 CPU,两者都非常低,但我的网络使用率不断上升,但图像已经在单元格上,所以这意味着它已经完成了。 (对于此测试,我只为 2 部电影调用 JSON,所以 2 张图像)
在我开始这样做之前,我的总下载量约为 200kb(带有图像),现在在我停止该项目之前它已经超过 2MB。
我做错了什么?
您可能希望为后台活动指定一个单独的队列。在这种情况下,您的繁重网络任务在:
NSData(contentsOf: url as URL)
这就是"freezing"的UI。最好的解决方案是定义类似 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
})
}
}
})
让我知道这是否有意义。
我正在从 json 下载图像 link,然后在 table 视图开始创建其单元格后创建图像:
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
}
这工作正常,但 table 视图变得非常慢,不是在渲染时而是在滚动时。我一直在检查 RAM 和 CPU,两者都非常低,但我的网络使用率不断上升,但图像已经在单元格上,所以这意味着它已经完成了。 (对于此测试,我只为 2 部电影调用 JSON,所以 2 张图像)
在我开始这样做之前,我的总下载量约为 200kb(带有图像),现在在我停止该项目之前它已经超过 2MB。
我做错了什么?
您可能希望为后台活动指定一个单独的队列。在这种情况下,您的繁重网络任务在:
NSData(contentsOf: url as URL)
这就是"freezing"的UI。最好的解决方案是定义类似 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
})
}
}
})
让我知道这是否有意义。