大佬教程收集整理的这篇文章主要介绍了ios – 如何获得许多图像的快速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滚动.
您在操作块中为@image分配整个集合视图类的私有变量.你应该改变:
@image = UIImage.imageWithContentsOfFile(image_path)
至
image = UIImage.imageWithContentsOfFile(image_path)
并更改@image的所有引用以使用局部变量.我愿意打赌,问题是每次创建一个操作块并分配给实例变量时,你正在替换已经存在的内容.由于操作块出现的一些随机性,主队列异步回调正在获得相同的图像,因为它正在访问最后一次@image被分配.
本质上,@image像操作和异步回调块的全局变量一样.
以上是大佬教程为你收集整理的ios – 如何获得许多图像的快速UICollectionView(50-200)?全部内容,希望文章能够帮你解决ios – 如何获得许多图像的快速UICollectionView(50-200)?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。