2014-10-03 2 views
2

У меня есть UICollectionView, который загружает изображения памяти iPad и отображает их в сетке, например, в приложении Apple Photos. В 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) 
       } 
      }) 
     }) 
    } 

Однако при прокрутке вид запаздывает, как будто он ждет изображения для загрузки, особенно с Retina графикой. Ячейки и изображения имеют размер 240x180 пикселей. Что-то не так с загрузкой изображения выше или нужно сделать еще одну оптимизацию?

ОБНОВЛЕНИЕ: Время профилировщик результаты enter image description here

+0

Изменить приоритет вашего потока от DISPATCH_QUEUE_PRIORITY_DEFAULT к DISPATCH_QUEUE_PRIORITY_BACKGROUND ИЛИ DISPATCH_QUEUE_PRIORITY_LOW, и посмотреть, если ваши взгляды коллекция выполняет лучше – EridB

+0

я пробовал, это не так. – Hristo

ответ

1

На линии

imageView.image = UIImage(contentsOfFile: img) 

Я загрузки изображения снова в главном потоке, а не image загружен асинхронно. Изменено на

imageView.image = image 

Прокрутка немного лучше, но все же нестабильная. Профилер времени показывает аналогичные результаты, как и раньше. Может ли узкое место быть в чертеже UIImageView? Он отлично работает с миниатюрами не сетчатки.

+0

Был готов опубликовать то же самое =) Рад, что вы его нашли. – Acey

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

в Swift:

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

Смежные вопросы