如何使用 NSCache 从 UICollectionView 中的 Web 服务器异步加载图像

2024-01-12

使用 NScache 从 UICollectionView 中的 Web 服务器加载图像时遇到一些问题。

问题:

图像未正确显示:

  1. 有时它们没有显示在相应的单元格中

or

  1. 图像在滚动时发生变化

情况:

  1. 我有 3 个数组,它们在函数 viewDidLoad() 中从 Web 服务器正确加载。这些数组是:vPrice、vTitle 和 vImages_api

  2. 我的单元格自定义类有:

    • 价格标签:cell.lblPrice

    • 标题标签:cell.lblTitle

    • 图片:cell.imgPicture

我相信问题出在函数 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell

它可能与我使用 NSCache 的方式有关,也可能与我使用 DispatchQueue 的方式和时间有关。

代码:

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

    cell.lblPrice.text = vPrice[indexPath.item]
    cell.lblTitle.text = vTitle[indexPath.item]

    cell.layer.borderColor = UIColor.lightGray.cgColor
    cell.layer.borderWidth = 0.5

    DispatchQueue.global(qos: .userInitiated).async {
        //background thread
        let ImageString = self.vImages_api[indexPath.item]
        let imageUrl = URL(string: ImageString)
        let imageData = NSData(contentsOf: imageUrl!)

        // main thread to update the UI
        DispatchQueue.main.async {
            let key1 = self.vImages_api[indexPath.item] as AnyObject
            //if i saved allready my image in cache, then i will load my image from cache
            if let imageFromCache = self.objCache.object(forKey: key1){
                cell.imgPicture.image = imageFromCache as! UIImage
            }
            else{//if my image is not in cache  ......
                        if imageData != nil {
                            let myPicture = UIImage(data: imageData! as Data)
                            cell.imgPicture.image = myPicture                 

                            //save my image in cache
                            self.objCache.setObject(myPicture!, forKey: ImageString as AnyObject)
                        }
            }
        }
    }

    return cell
}

编辑后的代码 - 版本 II:

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

    cell.lblPret.text = vPrice[indexPath.item]
    cell.lblTitlu.text = vTitle[indexPath.item]

    cell.layer.borderColor = UIColor.lightGray.cgColor
    cell.layer.borderWidth = 0.5
    let key1 = self.vImages_api[indexPath.item] as AnyObject

    if let imageFromCache = self.objCache.object(forKey: key1){
        cell.imgPicture.image = imageFromCache as! UIImage
    }else{
        DispatchQueue.global(qos: .background).async {
            let ImageString = self.vImages_api[indexPath.item]
            let imageUrl = URL(string: ImageString)
            let imageData = NSData(contentsOf: imageUrl!)
            let  myPicture = UIImage(data: imageData! as Data)
            self.objCache.setObject(poza!, forKey: ImageString as AnyObject)
                DispatchQueue.main.async {
                    if imageData != nil {
                        cell.imgPicture.image = myPicture
                    }
                }
        }

    }

    return cell
}

编辑后的代码 - 版本 III

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = self.collectionViewPRODUSE.dequeueReusableCell(withReuseIdentifier: "celula_custom", for: indexPath) as! clsCustomCell
    cell.lblPret.text = vPrice[indexPath.item]
    cell.lblTitlu.text = vTitle[indexPath.item]

  NKPlaceholderImage(image: UIImage(named: "loading"), imageView: cell.imgPicture, imgUrl:  self.vImages_api[indexPath.item]
    ) { (image11) in
        cell.imgPicture.image = image11
    }
    cell.layer.borderColor = UIColor.lightGray.cgColor
    cell.layer.borderWidth = 0.5

    return cell
}

试试这个它的工作代码(斯威夫特 4).

func NKPlaceholderImage(image:UIImage?, imageView:UIImageView?,imgUrl:String,compate:@escaping (UIImage?) -> Void){

    if image != nil && imageView != nil {
        imageView!.image = image!
    }

    var urlcatch = imgUrl.replacingOccurrences(of: "/", with: "#")
    let documentpath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    urlcatch = documentpath + "/" + "\(urlcatch)"

    let image = UIImage(contentsOfFile:urlcatch)
    if image != nil && imageView != nil
    {
        imageView!.image = image!
        compate(image)

    }else{

        if let url = URL(string: imgUrl){

            DispatchQueue.global(qos: .background).async {
                () -> Void in
                let imgdata = NSData(contentsOf: url)
                DispatchQueue.main.async {
                    () -> Void in
                    imgdata?.write(toFile: urlcatch, atomically: true)
                    let image = UIImage(contentsOfFile:urlcatch)
                    compate(image)
                    if image != nil  {
                        if imageView != nil  {
                            imageView!.image = image!
                        }
                    }
                }
            }
        }
    }
}

像这样使用:

// Here imgPicture = your imageView and UIImage(named: "placeholder") is Display image brfore download actual image.  
imgPicture.image = nil 
NKPlaceholderImage(image: UIImage(named: "placeholder"), imageView: imgPicture, imgUrl: "Put Here your server image Url Sting") { (image) in }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 NSCache 从 UICollectionView 中的 Web 服务器异步加载图像 的相关文章

随机推荐

  • 什么时候需要在 Tkinter 应用程序中调用 mainloop?

    我见过的每个 tkinter 教程都声称tkinter mainloop必须调用该函数来绘制窗口和处理事件 并且它们总是调用此函数 即使在 hello world 程序中也是如此 但是 当我在交互式 shell 中尝试这些时 窗口会正确绘制
  • 在Python中,len(list)有什么作用?

    Does len list 每次调用时计算列表的长度 还是返回内置计数器的值 我有一个上下文 我需要每次通过循环检查列表的长度 例如 listData for value in ioread if len listData gt 25 pr
  • Android 版 Firebase 突然无法在我的测试设备上运行

    我正在使用 Firebase 身份验证和实时数据库构建一个应用程序 昨天之前 在测试时它在我的设备中运行良好 但我现在甚至无法登录 Firebase 但该应用程序可以在我朋友的其他设备上运行 这里的实际问题是什么 在自己的真实设备上测试应用
  • jQuery dataTables:使用 jQuery 在单元格中使用换行符/换行符导出

    我正在尝试使用插件 jquery dataTable 生成可导出的数据表 但出于设计原因 我需要在单元格内进行换行 对于 HTML 视图 我简单地使用 br 但是如果我尝试将这个 f e 导出到 PDF 中 它将导致破坏第一个出现的 br
  • 使用 ReactJS 和 React Router 更改每个路由的页面背景颜色?

    使用 ReactJS 和 React Router 前往新路线时如何更改浏览器背景颜色 请参阅下面我的编辑 了解我一路上想到的想法 我可以让它工作 div 在每个页面视图中 但我需要它在完整背景上工作 以便完整浏览器窗口显示背景 我正在使用
  • 追加后如何检查元素是否存在?

    以下脚本应该附加一个元素 我首先检查该元素是否存在 如果不存在 我将创建它并附加它 问题是 由于某种原因 检查似乎不起作用 它不断地一遍又一遍地创建元素 问题 如何检查append后元素是否存在 我的jsfiddle https jsfid
  • 如何将IntelliJ与本地MySQL连接?

    我一直在努力学习如何在本地主机 MySQL 和 IntelliJ 上连接并编写数据库相关任务 那可能吗 如果是 如何实现 连接到本地实例与连接到远程 MySQL 实例本质上相同 只需将 localhost 或 127 0 0 1 替换为您通
  • firebase 可以 100% 离线运行并稍后同步吗?

    我需要构建一个用于任务工作的应用程序 该应用程序可以 100 离线运行 然后在重新连接到互联网时与服务器同步 该应用程序 目前 的数据库中有超过 6000 人 当传教士在现场时需要对其进行搜索 挑战在于我需要在多台笔记本电脑或平板电脑上本地
  • 将数组转换为对象数组

    如何将数组转换为 JavaScript 对象数组 例如我有一个数组 data fruits frozen fresh rotten apples 884 494 494 oranges 4848 494 4949 kiwi 848 33 3
  • 如何将 System.Data.SQLite 合并到单个可执行程序中?

    我正在尝试用 C 创建一个单一可执行应用程序 其中包括 SQLite System Data SQLite 依赖于一个非托管 DLL SQLite Interop dll 因此我无法将其与 ILMerge 合并 如何将 System Dat
  • 给定图上无向图 BFS 的“邻接矩阵”表示并输出顶点

    我可以在二维数组数组中找到BFS和DFS值 但是得分没有增加 我无法确切地弄清楚我做错了哪一部分 当我打印应该的值时 排序是正确的 但成绩仍然是 0 我对你的想法持开放态度 public class BFS DFS public stati
  • 在haproxy中使用环境变量

    希望有人能指出我正确的方向 我正在尝试将 HAProxy 配置为使用环境变量 来自操作系统 作为 acl 语句的一部分 因此 如果在启动或重新加载 HAProxy 时将环境变量设置为 true 则将授予访问权限 如果环境变量设置为 fals
  • bash 中的日期 - 月份没有前导 0 或空格?

    有人知道如何像这样显示日期吗 7 1 2019 我目前有这个 它在月份中添加前导 0 LC ALL nn NO UTF 8 date d m Y 像这样 7 01 2019 我在 lynx dump 命令中使用这些 您已经删除了当天的填充
  • 如何使用 Twitter Bootstrap 获取居中内容?

    我试图遵循一个非常基本的例子 使用起始页和网格系统 http getbootstrap com css grid 我希望以下内容 div class row div class span12 h1 Bootstrap starter tem
  • 大虾使用pdf模板

    我想用大虾生成一个使用PDF模板的文档 我没有收到任何错误 但模板被完全忽略 有谁知道为什么会这样 我真的很感激任何帮助 class JobPdf lt Prawn Document def initialize job super job
  • DI 容器如何工作的最简单解释?

    简单来说和 或在高级伪代码中 DI 容器如何工作以及如何使用 DI 容器的核心是基于以下内容创建对象 mappings接口和具体类型之间 这将允许您从容器请求抽象类型 IFoo f container Resolve
  • 头文件和标准库

    我是编程新手 目前正在学习C 我知道头文件仅包含声明和函数原型 而不包含函数本身 我对么 据我所知 库是一个包含不同目标代码的单个文件 这些目标代码是否必须只能用C语言编写 或者也可以使用其他语言来生成这样的目标代码 在链接时 整个库文件是
  • JXBrowser java.ipc.external=true 虚拟机参数

    我想知道这个论证到底是做什么的 并了解潜在的缺点这个争论可能会导致 我尝试在互联网上搜索这个虚拟机参数 但我找不到任何内容 默认情况下 在 macOS 上 JxBrowser 在 Java 进程中初始化 Chromium 引擎 Chromi
  • 当 2 个测试用例失败时,Gitlab CI 管道中的测试标记为通过

    我们有一个在 Gitlab 中管理的项目 带有用于构建和测试 pytest Google 测试 的 CI 管道 我们在 Google 测试中的两三个测试用例失败了 但Gitlab认为测试阶段是成功的 是因为成功率超过90 任意值 吗 如果我
  • 如何使用 NSCache 从 UICollectionView 中的 Web 服务器异步加载图像

    使用 NScache 从 UICollectionView 中的 Web 服务器加载图像时遇到一些问题 问题 图像未正确显示 有时它们没有显示在相应的单元格中 or 图像在滚动时发生变化 情况 我有 3 个数组 它们在函数 viewDidL