Swift 中从 Core Data 异步加载图像

Jor*_*416 2 iphone asynchronous core-data ios uicollectionview

我正在构建一个使用核心数据数据库来存储产品数据的应用程序。这些产品显示在UICollectionView. 此集合视图中的每个单元格都显示其包含的产品的基本信息,包括图像。

尽管单元相对较小,但它们显示的原始图像优选地相当大,因为它们还应该能够在更大的图像视图中显示。在我的方法中,图像是直接从核心数据加载的CellForItemAtIndexPath:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionWineCell

        var current: Product!

        //product details are set on labels

        //image is set
        if current.value(forKey: "image") != nil {
            let image = current.value(forKey: "image") as! WineImage
            let loadedImage = UIImage(data: image.image)
            cell.imageview.image = loadedImage
        } else {
            cell.imageview.image = UIImage(named: "ProductPlaceholder.png")
        }

        return cell
    }
Run Code Online (Sandbox Code Playgroud)

当产品集合增加时,滚动会变得更加颠簸,并且许多帧会丢失。这对我来说很有意义,但到目前为止我还没有找到合适的解决方案。在线查看时,有很多文档和框架可用于从 URL(在线或文件路径)异步加载图像,但从 Core Data 执行此操作似乎并不常见。

我已经尝试过使用异步获取请求来做到这一点:

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName:"ProductImage")
        fetchRequest.predicate = NSPredicate(format: "product = %@", current)
        let asyncRequest = NSAsynchronousFetchRequest(fetchRequest: fetchRequest) { results in
            if let results = results.finalResult {
                let result = results[0] as! ProductImage
                let loadedImage = UIImage(data: result.image)
                DispatchQueue.main.async(execute: {
                    cell.wineImage.image = loadedImage
                })
            }
        }
        _ = try! managedObjectContext.executeRequest(asyncRequest)
Run Code Online (Sandbox Code Playgroud)

然而,这种方法似乎也没有使事情变得顺利

问题 当显示来自 Core Data 的大量数据(包括图像)时,如何以一种不会导致延迟和帧丢失的方式加载图像UICollectionView

Tom*_*ton 5

如果图像如您所说,非常大,更好的方法不是将它们保存在 Core Data 中,而是将它们放入文件中。将文件名存储在 Core Data 中并使用它来查找文件。

但这不是眼前的问题。即使如此,您也会因为花费时间打开和解码图像数据而导致速度变慢。基本上,更好的方法是不要这样做。在您的收藏视图中,显示的图像可能比其完整尺寸小得多。不要使用完整尺寸的图像,而是生成更合适尺寸的缩略图并在集合视图中使用它。每当您第一次获取图像时,无论是从下载的图像还是从用户的照片库或其他任何地方获取图像,都应生成缩略图。保留缩略图以在集合视图中使用。仅在真正需要时才使用全尺寸图像。

网上有很多关于如何缩放图像的示例,所以这里不再赘述。