【问题标题】:Slow UICollectionView with asynchronous loading带有异步加载的慢 UICollectionView
【发布时间】:2014-10-03 20:53:13
【问题描述】:

我有一个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 大。上面的图片加载有什么问题还是需要进一步优化?

更新:时间分析器结果

【问题讨论】:

  • 将线程的优先级从 DISPATCH_QUEUE_PRIORITY_DEFAULT 更改为 DISPATCH_QUEUE_PRIORITY_BACKGROUND 或 DISPATCH_QUEUE_PRIORITY_LOW,看看您的收藏视图是否表现更好
  • 我试过了,不行。

标签: ios asynchronous swift uiimage uicollectionview


【解决方案1】:

您已经发现您正在将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 再次清除其内部图像数据以释放资源。

【讨论】:

    【解决方案2】:

    上线

    imageView.image = UIImage(contentsOfFile: img)
    

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

    imageView.image = image
    

    滚动稍微好一点,但又不连贯。时间分析器显示与以前类似的结果。瓶颈可能在 UIImageView 绘图中吗?它适用于非视网膜缩略图。

    【讨论】:

    • 正要发布同样的内容 =) 很高兴你找到了。
    【解决方案3】:

    瓶颈是一些缩略图缩放不当,比 UIImageView 大很多,导致加载时间较长。我还认为这会导致绘制速度变慢,因为 UIImage 必须按比例缩小以适合 UIImageView。

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

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

    【讨论】:

      【解决方案4】:

      在斯威夫特中:

          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
      

      【讨论】:

      • 您能否解释一下光栅化代码的作用以及它如何提高性能?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-19
      • 2020-07-15
      • 1970-01-01
      • 2017-02-25
      • 1970-01-01
      相关资源
      最近更新 更多