HTML5   发布时间:2022-04-27  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 如何获得许多图像的快速UICollectionView(50-200)?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用UICollectionView在一个应用程序中显示相当多的照片(50-200),我有问题让它变得快乐(例如像照片应用程序).

我有一个自定义UICollectionViewCell与UIImageView作为子视图.我正在使用UIImage.imageWithContentsOfFile :,将文件系统中的图像加载到单元格内的UIImageView中.

我现在已经尝试了很多方法,但是它们已经是bug或者性能问题.

注意:我使用@L_680_10@motion,所以我将使用Ruby样式编写任何代码片段.

首先,这是我的自定义UICollectionViewCell类来引用…

class Customcatell < UICollectionViewCell
  def initWithFrame(rect)
    super

    @image_view = UIImageView.alloc.initWithFrame(self.bounds).tap do |iv|
      iv.contentMode = UIViewContentModeScaleAspectFill
      iv.clipsToBounds = true
      iv.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth
      self.contentView.addSubview(iv)
    end

    self
  end

  def prepareForReuse
    super
    @image_view.image = nil
  end

  def image=(imagE)
    @image_view.image = image
  end
end

方法#1

保持简单

def collectionView(collection_view,cellForItemATindexPath: index_path)
  cell = collection_view.dequeueReusableCellWithReusEIDentifier(CELL_IDENTIFIER,forIndexPath: index_path)
  image_path = @image_paths[index_path.row]
  cell.image = UIImage.imageWithContentsOfFile(image_path)
end

使用此向上/向下滚动是可怕的.这是跳跃和缓慢.

方法#2

通过NSCache添加一些缓存…

def viewDidLoad
  ...
  @images_cache = NSCache.alloc.init
  ...
end

def collectionView(collection_view,forIndexPath: index_path)
  image_path = @image_paths[index_path.row]

  if cached_image = @images_cache.objectForKey(image_path)
    cell.image = cached_image
  else
    image = UIImage.imageWithContentsOfFile(image_path)
    @images_cache.setObject(image,forKey: image_path)
    cell.image = image
  end
end

再次,第一个完整的滚动跳跃和缓慢,但从那以后,它是顺利的航行.

方法#3

加载图像异步…(并保持缓存)

def viewDidLoad
  ...
  @images_cache = NSCache.alloc.init
  @image_loading_queue = NSOperationQueue.alloc.init
  @image_loading_queue.maxConcurrentOperationCount = 3
  ...
end

def collectionView(collection_view,forIndexPath: index_path)
  image_path = @image_paths[index_path.row]

  if cached_image = @images_cache.objectForKey(image_path)
    cell.image = cached_image
  else
    @operation = NSBlockOperation.blockOperationWithBlock lambda {
      @image = UIImage.imageWithContentsOfFile(image_path)
      Dispatch::Queue.main.async do
        return unless collectionView.indexPathsForVisibleItems.containsObject(index_path)
        @images_cache.setObject(@image,forKey: image_path)
        cell = collectionView.cellForItemATindexPath(index_path)
        cell.image = @image
      end
    }
    @image_loading_queue.addoperation(@operation)
  end
end

这看起来很有希望,但是有一个我无法追踪的错误.在初始视图加载时,所有图像都是相同的图像,当您滚动整个块加载与另一个图像,但都具有该图像.我试过调试,但我无法想像出来.

我也尝试用Dispatch :: Queue.concurrent.async {…}替换NSOperation,但是似乎是一样的.

我认为这可能是正确的方法,如果我能让它正常工作.

方法#4

在沮丧中,我决定将所有图像预先加载为UIImages …

def viewDidLoad
  ...
  @preloaded_images = @image_paths.map do |path|
    UIImage.imageWithContentsOfFile(path)
  end
  ...
end

def collectionView(collection_view,forIndexPath: index_path)
  cell.image = @preloaded_images[index_path.row]
end

在第一个完整的卷轴中,结果变得有点慢,跳跃,但一切顺利.

概要

所以,如果有人能指出我正确的方向,我会非常感激.照片应用程序如何做得很好?

注意其他人:[被接受]的答案解决了我的图像出现在错误的单元格的问题,但即使在调整我的图像大小以正确的大小后,我仍然正在滚动滚动.在将我的代码剥离到裸机之后,我最终发现UIImage#imageWithContentsOfFile是罪魁祸首.即使我使用这种方法预热了UIImages的缓存,UIImage似乎在内部做一些懒惰的缓存.更新我的缓存加温代码以使用这里详细说明的解决方案 – stackoverflow.com/a/10664707/71810 – 我终于有超级光滑〜60FPS滚动.

解决方法

我认为#3方法是最好的方法,我想我@R_401_9381@这个bug.

您在操作块中为@image分配整个集合视图类的私有变量.你应该改变:

@image = UIImage.imageWithContentsOfFile(image_path)

image = UIImage.imageWithContentsOfFile(image_path)

并更改@image的所有引用以使用局部变量.我愿意打赌,问题是每次创建一个操作块并分配给实例变量时,你正在替换已经存在的内容.由于操作块出现的一些随机性,主队列异步回调正在获得相同的图像,因为它正在访问最后一次@image被分配.

本质上,@image像操作和异步回调块的全局变量一样.

大佬总结

以上是大佬教程为你收集整理的ios – 如何获得许多图像的快速UICollectionView(50-200)?全部内容,希望文章能够帮你解决ios – 如何获得许多图像的快速UICollectionView(50-200)?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。