2014-10-03 55 views
2

我有一个UICollectionView加载iPad的内存的图像,并显示在网格,如苹果的照片应用程序。所述UICollectionViewCell负载异步缩略图:与异步加载缓慢UICollectionView

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) 
       } 
      }) 
     }) 
    } 

然而,虽然滚动视图滞后,就好像它在等待图像加载,特别是与视网膜图形。单元格和图像大小约为240x180像素。上面的图片加载有什么问题吗?还是需要进一步优化?

UPDATE:时间探查结果 enter image description here

+0

从DISPATCH_QUEUE_PRIORITY_DEFAULT更改线程的优先级,以DISPATCH_QUEUE_PRIORITY_BACKGROUND OR DISPATCH_QUEUE_PRIORITY_LOW,看看你收集的意见进行更好 – EridB 2014-10-03 20:57:50

+0

我试过了,事实并非如此。 – Hristo 2014-10-03 21:00:00

回答

1

上线

imageView.image = UIImage(contentsOfFile: img) 

我是主线程,而不是image异步加载重新加载图像。更改为

imageView.image = image 

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

+0

即将发布相同的事情=)很高兴你找到它。 – Acey 2014-10-03 21:08:36

2

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

0

瓶颈在于某些缩略图缩放比例不当,比UIImageView大得多,导致加载时间更长。我也认为这造成了较慢的绘图,因为UIImage必须缩小以适应UIImageView。

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

P.S.我还修复了最初代码中错位的UIImage(contentsOfFile: img)变量,请参阅我的其他答案。

0

斯威夫特:

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 
+1

您能否解释一下栅格化代码的作用以及它如何提高性能? – JK140 2017-05-06 15:42:13