我开发了一个应用程序,它像 Tinder 一样在 UICollectionView
中显示“全屏卡片”。该卡片包含图像和一些文本。我在 UICollectionView
的单元格中使用 SDWebImage
的 sd_setImageWithURL
方法加载图像。
然而,这并没有给我带来良好的性能,因为图像大多是在用户在卡上时加载的。因此,我使用 SDWebImagePrefetcher
预取队列来执行此操作,如下所示:-
func startImagePreloadingOperationForIndex(index:Int)
{
let numberOfImagesToBePreloadedOnEachSide = 20
var previousIndex = index - numberOfImagesToBePreloadedOnEachSide
var nextIndex = index + numberOfImagesToBePreloadedOnEachSide
if previousIndex < 0
{
previousIndex = 0
}
if nextIndex >= currentNewsCollection.count
{
nextIndex = currentNewsCollection.count - 1
}
if previousIndex >= nextIndex || currentNewsCollection.isEmpty
{
return
}
let arrayOfNewsStories = currentNewsCollection[previousIndex...nextIndex]
let arrayOfImageURLs = arrayOfNewsStories.map( { ImageUtility.getImageStringForNewsStory($0) } )
SDWebImagePrefetcher.sharedImagePrefetcher().prefetchURLs(arrayOfImageURLs, progress: { (x, y) -> Void in
}) { (x, y) -> Void in
}
}
当用户登陆特定卡片时调用此函数。预取队列自动管理不在缓存中下载图像,所以我不必担心。除此之外,我还在 cellForItemAtIndexPath
中使用 sd_setImageWithURL
从缓存中获取下载的图像。
这是一个更好的解决方案,因为我现在在用户使用卡片时预加载图像。然而,这是一个并行队列。这意味着图像没有。 index + 20 可以在当前图像之前加载,用户可能不得不等待图像。此外,如果用户滚动浏览 50 多张卡片并且内存使用量也不断增加,应用程序会变得有点迟钝。
任何人都可以提出对此或更好算法的改进建议吗?
谢谢
最佳答案
使用 sd_setImageWithURL 下载当前卡上的图像,并在完成处理程序中开始下载预取队列。这样当前图像始终享有最高优先级,不会滞后。
currentCardImageView.sd_setImageWithURL(url) { (image, error, imageCacheType, url) in
// start prefetching here
}
如果当前图像已经下载,SDWebImage 会识别并从缓存中获取它。
另一个延迟和高内存消耗的问题可能可以通过减少预取图像的数量来解决。 20个挺高的,5个应该够了,不过这个要看图片大小,网速等...
另一件事:SDWebImage 有一个 maxConcurrentOperationCount 属性。从 1 开始,测试,增加到 2,测试,增加……等等。直到找到它滞后的点。
关于ios - iOS 中的图像预加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36326096/