首页 文章

从Swift中的Core Data加载异步图像

提问于
浏览
0

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

尽管单元格相对较小,但它们显示的原始图像优选地非常大,因为它们也应该能够以更大的图像视图显示 . 图像直接从我的 CellForItemAtIndexPath: 方法中的Core Data加载:

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
    }

当产品集合增长时,滚动变得更加崎岖,并且丢弃了许多帧 . 这对我来说很有意义,但到目前为止我还没有找到合适的解决方案 . 在线查看时,许多文档和框架可用于从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)

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

QUESTION 当从Core Data显示大量数据(包括图像)时,如何以不会导致滞后和帧丢失的方式加载图像?

1 回答

  • 1

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

    但这不是当前的问题 . 即使这样,你也会因为花时间打开和解码图像数据而减速 . 基本上,更好的方法是不要这样做 . 在您的集合视图中,图像可能显示的尺寸远小于其完整尺寸 . 而不是使用完整大小的图像,生成更合适的缩略图,并在集合视图中使用它 . 无论是从下载还是从用户的照片库或任何地方获取图像,都可以生成缩略图 . 保留缩略图以在集合视图中使用 . 只在真正需要时使用全尺寸图像 .

    网上有很多关于如何缩放图像的例子,所以我不会在这里包含它 .

相关问题