UIImage 被加载,在滚动通过 1 个单元格后,它会滞后并继续其他单元格。
extension TableViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return post.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "myCell")
DispatchQueue.main.async {
//MARK:- UIImage as URL
let postImage = self.post[indexPath.row]
if let photoUrl = URL(string: postImage.photoUrl!)
{
do {
let data = try Data(contentsOf: photoUrl)
cell.imageView?.image = UIImage (data: data)
cell.imageView?.frame = CGRect(x: 0, y: 0, width: 450, height: 450)
} catch {
print("")
}
}// postImage
}
return cell
}
} //MARK:- Extension into Table View Controller
它滞后是因为您在主线程上进行“繁重”操作。DispatchQueue.main.async 在这里没有帮助,因为它仍然在主线程中执行代码。你真的必须在主线程上做这两行代码:
cell.imageView?.image = UIImage (data: data)
cell.imageView?.frame = CGRect(x: 0, y: 0, width: 450, height: 450)
实际上,您甚至不需要第二个,因为布局应该由单元格本身完成(例如,您可以通过约束或自动调整大小掩码设置它)
The heaviest operation in your code is let data = try Data(contentsOf: photoUrl)
because it performs data loading from network. So your main goal is to perform this operation out of main thread. For example you can do it like this:
DispatchQueue.global().async {
do {
let data = try Data(contentsOf: photoUrl)
let image = UIImage(data: data) // this also could be pretty much heavy if the image is big so since we're already in background let's do it here
DispatchQueue.main.async {
imageView.image = UIImage (data: data)
}
}
catch {
print("")
}
}
This example is pretty much basic and still has unsolved problems. For example, if image is very large than scaling it when it's set to imageView also could be expensive, so you'd better also scale image to imageView size in background thread. Also cells are reusable so when one image is loaded the cell could already be used for displaying another image so you also need a way to handle it. Also you'll probably want to cache loaded images to avoid reloading them from network every time on scroll.
所以这里有很多工作要做,为了让它更容易,我建议使用像Kingfisher这样的库(而不是作为例子的广告)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句