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

时间:2018-11-14 17:25:42

标签: swift macos asynchronous uicollectionview

我正在尝试将一些本地保存的图像(使用Disk)加载到 UICollectionView 。每当我尝试获取它们时,应用程序就会挂起约10秒钟。这告诉我我做错了什么。

我正在考虑异步加载它们,并且每当其中一个加载时,首先显示它。但是,我将它们放在本地存储中,为什么要花这么多时间来加载它们?

图像是从用户的iPhone导入的,未压缩。加载它们时,我正在加载整个图像(我知道这很不好)。

有人可以指出我正确的方向吗?

这是加载过程的第一部分:

   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)") }
    }
}

这是第二部分

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([])
            }
        }
    }
}

显示方式如下。基本上,它返回整个数组并重新加载集合视图

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

1 个答案:

答案 0 :(得分:0)

这里的问题不是访问本地存储的速度,而是图像的渲染。您正在从存储中加载所有图像并进行渲染,即使对于可能不在屏幕上的集合视图单元,也要在显示任何内容之前进行渲染。

解决此问题的通常方法是让集合视图在单元格滚动查看时异步请求该单元格的图像。即视图应从模型中提取每个图像,而不是尝试将模型中的图像推入视图。

关于如何正确执行此操作的完整说明太长,无法在此处找到答案,但是有许多示例和教程介绍了如何执行此操作,只是Google异步加载或延迟加载。还要看看iOS 10中引入的预取API。

例如参见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