从 NSData 转换到 UIImage 很慢,阻塞 UITableView
Posted
技术标签:
【中文标题】从 NSData 转换到 UIImage 很慢,阻塞 UITableView【英文标题】:Transform from NSData to UIImage very slow, block UITableView 【发布时间】:2017-09-23 00:07:01 【问题描述】:我从Core Data
获得NSData,当我从NSData
转换为UIImage
时,它使我的UITableView 滚动非常缓慢。在将图像存储到Core Data
之前,我已经调整了图像的大小。有没有好的方法来做到这一点。一开始想用Kingfisher
,但是好像没有这种方法可以实现。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cellIdentifier = "ListTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? ListTableViewCell else
fatalError("The dequeued cell is not an instance of MealTableViewCell.")
//cell.imageContentPhoto.kf.setImage(with: url)
cell.imageContentPhoto.image = UIImage(data: photos[indexPath.row] as Data)//photo is NSData, I got it from Core Data
return cell
【问题讨论】:
【参考方案1】:您的问题不在于转换速度很慢,而是在您滚动时它已经完成了很多次。
为了优化 UITable,ios 不会为 n 行创建 n 个单元格。它创建 x+2 个单元格 (IIRC),其中 x 是 可见 单元格的数量。
当 cellForRowAt 被调用时,你调用 dequeueReusableCell,它获取一个空闲单元并将其分配给行。这样,当您滚动时,不会发生对象初始化,并减慢滚动速度。
您的代码的问题(现在很明显)是在将单元格分配给行之后,您再次转换图像并对其进行初始化。
您应该提前初始化图像数组,例如在 viewDidLoad 中。那么您的代码将如下所示:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cellIdentifier = "ListTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? ListTableViewCell else
fatalError("The dequeued cell is not an instance of MealTableViewCell.")
//cell.imageContentPhoto.kf.setImage(with: url)
cell.imageContentPhoto.image = imagesArray[indexPath.row] // or something similar
return cell
当然,如果您有很多不同的图像,那么进行某种延迟加载可能是值得的。滚动时保留占位符图像,当它停止时,仅加载相关图像。这当然要复杂得多,留给学生作为练习。
【讨论】:
非常感谢。你解决了我的问题。现在我将做这些复杂的事情,放置一个持有人图像,并仅加载相关图像。这对我来说有点困难。我会检查更多相关材料。谢谢~以上是关于从 NSData 转换到 UIImage 很慢,阻塞 UITableView的主要内容,如果未能解决你的问题,请参考以下文章
直接从 AFNetworking 获取 NSData,而不是让它转换为 UIImage
将UIImage转换为NSData并在Swift中转换回UIImage?