简体   繁体   English

从本地存储将UIImages加载到collectionView非常慢

[英]Loading UIImages to collectionView from local storage is very slow

I am trying to load some images saved locally (using Disk ) to a UICollectionView . 我试图将一些本地保存的图像(使用Disk )加载到UICollectionView Whenever I try to fetch them, the app hangs for about 10 seconds. 每当我尝试获取它们时,应用程序就会挂起约10秒钟。 This tells me I am doing something very wrong. 这告诉我我做错了什么。

I am thinking of loading them asynchronously and whenever one of them loads, displaying it first. 我正在考虑异步加载它们,并且每当其中一个加载时,首先显示它。 However, I have them on local storage so why does it take so much time to load them? 但是,我将它们放在本地存储上,为什么要花这么多时间来加载它们?

The images are imported from the user's iPhone and are not compressed. 图像是从用户的iPhone导入的,未压缩。 When loading them, I am loading the whole image (I know it's bad). 加载它们时,我正在加载整个图像(我知道这很不好)。

Can someone point me towards the right direction? 有人可以指出我正确的方向吗?

Here is the first part of the loading process: 这是加载过程的第一部分:

   func fetchImage(path: String, imageID: String, completionHandler: @escaping (() throws -> UIImage) -> Void) {
    do {
        let imagePath = path + imageID + ".png"
        let image = try Disk.retrieve(imagePath, from: .documents, as: UIImage.self)
        completionHandler{ return image }
    } catch {
        completionHandler{ throw AlbumStoreError.CannotFetch("Cannot fetch Image with Error: \(error)") }
    }
}

here Is the second part 这是第二部分

func fetchImages(path: String, completionHandler: @escaping ([UIImage]) -> Void) {
    albumsStore.fetchImages(path: path) { (images: () throws -> [UIImage]) in
        do{
            let images = try images()
            DispatchQueue.main.async {
                completionHandler(images)
            }
        } catch {
            DispatchQueue.main.async {
                completionHandler([])
            }
        }
    }
}

here is how it's presented. 这是它的呈现方式。 Basically it returns the whole array and reloads the collection view 基本上,它返回整个数组并重新加载集合视图

func presentImages(response: Collage.Images.Save.Response){
    let images = response.images
    let viewModel = Collage.Images.ViewModel(images: images)
    viewController?.displayImages(viewModel: viewModel) }

The problem here is not speed of access to local storage, but rendering of images. 这里的问题不是访问本地存储的速度,而是图像的渲染。 You are loading all images from storage and rendering them, even for collection view cells which may be off screen, before displaying anything. 您正在从存储中加载所有图像并进行渲染,即使对于可能不在屏幕上的集合视图单元,也要在显示任何内容之前进行渲染。

The usual way to handle this is to have the collection view request an image for a cell asynchronously as that cell scrolls in to view. 解决此问题的通常方法是让集合视图在单元格滚动查看时异步请求该单元格的图像。 ie the view should pull each image from the model, rather than trying to push images from your model into the view. 也就是说,视图应从模型中提取每个图像,而不是尝试将模型中的图像推入视图。

A complete explanation of how to do this properly is too long for an answer here but there are any number of examples and tutorials on how to do this, just Google asynchronous loading, or lazy loading. 关于如何正确执行此操作的完整说明太长,无法在此处找到答案,但是有许多示例和教程介绍了如何执行此操作,只是Google异步加载或延迟加载。 Also look at the prefetching API introduced in iOS 10. 还要看看iOS 10中引入的预取API。

See for example https://medium.com/capital-one-tech/smooth-scrolling-in-uitableview-and-uicollectionview-a012045d77f or Apple's documentation on prefetch: https://developer.apple.com/documentation/uikit/uicollectionviewdatasourceprefetching/prefetching_collection_view_data 参见例如https://medium.com/capital-one-tech/smooth-scrolling-in-uitableview-and-uicollectionview-a012045d77f或有关预取的Apple文档: https : //developer.apple.com/documentation/uikit/ uicollectionviewdatasourceprefetching / prefetching_collection_view_data

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM