使用异步加载缓慢UICollectionView

我有一个UICollectionView ,它可以加载iPad内存的图像并将它们显示在网格中,就像Apple的照片应用程序一样。 UICollectionViewCell异步加载缩略图:

  func setImage(img:String){ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { //load the image in the background let image = UIImage(contentsOfFile: img) //when done, assign it to the cell's UIImageView dispatch_async(dispatch_get_main_queue(), { if let imageView = self.imageView{ imageView.image = UIImage(contentsOfFile: img) } }) }) } 

但是,滚动视图时会像等待图像加载一样滞后,尤其是使用Retina图形时。 细胞和图像大约240x180px。 上面的图像加载有什么问题或需要进一步优化吗?

更新:时间分析器结果 在此处输入图像描述

你已经发现你正在主队列上再次加载UIImage ; 修复这将有所帮助。

在大多数情况下, UIImage延迟加载其内部图像数据。 一个技巧是在仍然在后台队列上时调用其CGImage属性以强制它实际创建其内部图像数据,而不是在第一次绘制图像视图时延迟加载它:

 func setImage(img:String){ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { //load the image in the background let image = UIImage(contentsOfFile: img) image.CGImage // <- Force UIImage to not lazy load the data //when done, assign it to the cell's UIImageView dispatch_async(dispatch_get_main_queue(), { if let imageView = self.imageView { imageView.image = image } }) }) } 

注意:如果您有大量图像,最终可能会很快收到内存警告。 如果这样做,这可能无济于事,因为内存警告通常会导致UIImage再次清除其内部图像数据以释放资源。

在线上

 imageView.image = UIImage(contentsOfFile: img) 

我在主线程上再次加载图像,而不是异步加载的image 。 变成

 imageView.image = image 

滚动有点好,但不稳定。 时间分析器显示与以前类似的结果。 可能是UIImageView绘图中的瓶颈? 它适用于非视网膜缩略图。

瓶颈是一些缩略图缩放不正确并且比UIImageView大很多,这导致更长的加载时间。 我也认为这导致了较慢的绘图,因为UIImage必须缩小尺寸以适应UIImageView。

我修复了缩略图生成代码,滚动再次平滑。

PS我还在初始代码中修复了错误放置的UIImage(contentsOfFile: img)变量,请参阅我的其他答案。

在斯威夫特:

  let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT dispatch_async(dispatch_get_global_queue(priority, 0)) { let imagem = UIImage(named :"image") dispatch_async(dispatch_get_main_queue()) { cell.IMG_Novidades.image = imagem } } //THIS IS VERY IMPORTANT cell.layer.shouldRasterize = true cell.layer.rasterizationScale = UIScreen.mainScreen().scale