2014-10-03 75 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