如何使用 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 服务器异步加载图像 的相关文章

  • 多线程:只有在执行完其他方法后才调用执行方法

    我正在尝试根据要求异步处理方法 一旦第一个方法完成 只有第二个方法应该开始执行 问题是第一个方法本身具有在后台线程上运行的代码 我尝试了dispatch semaphore wait 但这也不起作用 dispatch queue t que
  • 无法构建 Objective-C 模块“Firebase”

    我收到此错误的原因是import Firebase 无法构建 Objective C 模块 Firebase Xcode 还抱怨 FirebaseAnalytics 说 找不到 FirebaseAnalytics FirebaseAnaly
  • AVPlayerLooper 每次迭代后黑闪

    我正在使用 Apple 的示例代码在UICollectionViewCell背景 我在用着AVPlayerLooper 因为它是同一视频的迭代 我的问题是 当视频结束时 它会显示轻微的黑屏闪烁 也许它正在将视频搜索到0时间 我不确定 这是代
  • 如何提高包含大量小图像的 UCollectionView 的性能?

    在我的 iOS 应用程序中我有UICollectionView显示大约 1200 个小 35x35 点 图像 图像存储在应用程序包中 我正确地重用了UICollectionViewCell但仍然存在性能问题 具体取决于我处理图像加载的方式
  • 如何在 UICollectionView 的节标题中动态添加标签和按钮?

    请帮助我如何水平添加标签和水平添加类似的按钮 但每个按钮应像另一个部分一样在每个标签的下方对齐 这应该在 UICollectionView 的标题中动态发生 因为标签和按钮的数量根据我的数据 我想制作一种 Excel 类型的布局 并在标题中
  • UICollectionView 未出现

    我正在尝试设置UICollectionView 以编程方式在我的视图控制器中扩展UIViewController 由于某种原因 我的收藏视图根本没有显示 以下是我所拥有的 为什么没有出现 我将它连接到委托和数据源并将其添加为子视图self
  • Swift:UICollectionViewCell didSelectItemAtIndexPath 更改背景颜色

    我可以轻松更改单元格的背景颜色CellForItemAtIndexPath method func collectionView collectionView UICollectionView cellForItemAtIndexPath
  • 如何获得包含大量图像(50-200)的快速 UICollectionView?

    我在用着UICollectionView在一个显示大量照片 50 200 的应用程序中 我在让它变得活泼 例如像照片应用程序一样活泼 时遇到问题 我有一个习惯UICollectionViewCell with a UIImageView因为
  • UICollectionView PerformBatchUpdates 同时插入、删除、移动

    我正在尝试使用UICollectionView s performBatchUpdates方法来执行过滤操作 某种 并且在块内我插入单元格 移动单元格和删除单元格 我得到了一些奇怪的结果 所以我想知道这种行为是否真的受到支持 我认为索引变得
  • UICollectionview 单元格选择

    我制作了一个图像网格 为了显示其选择 我在选择时为图像绘制了边框 但问题是 当我选择顶部的一些图像并向下滚动图像网格时 底部的其他一些图像似乎也被选择了 下面是我的代码片段 UINib cellNib UINib nibWithNibNam
  • UICollectionView 设置列数

    我刚刚开始学习 UICollectionViews 我想知道是否有人知道如何指定集合视图中的列数 默认设置为 3 iPhone 肖像 我查看了文档 似乎找不到简洁的答案 对于 Swift 5 和 iOS 12 3 您可以使用4 以下实现为了
  • Grand Central Dispatch (GCD) 调度源标志

    我最近不再使用 to GCD 调度来源 https developer apple com documentation dispatch 1385630 dispatch source create监视文件更改 效果很好 API 也变得更加
  • 根据图像制作具有 UIImageView 高度的 UICollectionViewCells

    我想做一个UICollectionView单元格的宽度是屏幕的宽度 但高度取决于单元格的宽高比UIImageView inside 在我目前的实施中 所有UICollectionViewCell实例是正方形 这不是我想要的 我想以某种方式使
  • 如何检查dispatch_async块是否已完成运行

    所以基本上我需要能够在块完成运行后运行 segue 我有一个块可以执行一些 JSON 操作 我需要知道它何时完成运行 我有一个队列 我称之为 json queue jsonQueue dispatch queue create com ja
  • 在 Swift 中监听 stdin

    目前 我正在尝试在我的 swift 应用程序中监听来自命令行的用户输入 我知道readLine 方法 但它并不真正符合我的需求 我想监听在命令行上插入的数据 就像用户在终端内按下 向上键 一样 类似于 Node js 中可以完成的事情 st
  • 当应用程序置于后台时,GCD 分派操作未运行

    我启动了一种方法 本质上是一个无限循环 使用dispatch queue create进而dispatch async 然后代码循环位于分派块内 循环完美运行 但是 当应用程序进入后台时 它会暂停 然后当应用程序进入前台时它会重新启动 我怎
  • UICollectionView 滚动到任何页脚或页眉视图

    我想滚动到集合视图的页脚或标题视图 但是 标准方法是scrollToItemAtIndexPath仅滚动到单元格 void scrollToBottom NSInteger section self numberOfSectionsInCo
  • 为什么 UICollectionView didSelect 方法不起作用?

    我已经创建了我的UICollectionView以编程方式 在这种情况下我的didSelectItemAtIndexPath方法根本不调用 let collectionView UICollectionView frame CGRect x
  • 如何在 swift 4 中进行两个并发 API 调用

    预先感谢您的帮助 我有两个 API 调用 都是并发的 任何调用都可以先成功 我不想按顺序调用 在两个调用成功后 我必须停止我的活动指示器并重新加载我的 tableView 这是我的代码 但我不知道这是正确的方法 也不知道如何重新加载我的 t
  • 如何使用 IOS 12 在 UITableViewCell 中正确添加 UICollectionView

    由于某些原因 在使用 Xcode 10 beta 时 我无法正确显示 tableview 单元格内集合中的某些项目 在过去的四天里我尝试了我所知道的一切 我做了一个小项目样本来看看我的问题是什么 如果有人想在本地运行完整代码 请参见此处 h

随机推荐

  • 什么时候需要在 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