iOS开发进阶之列表加载图片

iOS开发进阶之列表加载图片

列表加载图片通常使用UITableViewUICollectionView,由于列表中内容数量不确定并且对于图片质量要求也不确定,所以对于图片加载的优化是很有必要的。
iOS开发进阶之列表加载图片
首先借鉴前文,我们逐步进行操作,以下是加载1000张图片的列表。

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {return 1000}func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UICollectionViewCell", for: indexPath)cell.contentView.layer.contents = UIImage(named: "iOS")?.cgImagereturn cell}

实验结果
可以看到在使用复用机制后,我们的内存占用还比较低,我们接下来换网络图片。
对应代码调整,以下。

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UICollectionViewCell", for: indexPath)let vi = UIImageView(frame: CGRect(origin: .zero, size: CGSize(width: 150, height: 100)))vi.kf.setImage(with: URL(string: "https://img0.baidu.com/it/u=245753553,2056265008&fm=253&fmt=auto?w=1280&h=800")!)cell.contentView.addSubview(vi)return cell}

实验结果
此时的网络图片对应尺寸会比较大,在滚动时可以明显感受到卡顿,接下来换一下加载方式,以下。

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UICollectionViewCell", for: indexPath)DispatchQueue.global(qos: .background).async {let url = "https://img0.baidu.com/it/u=245753553,2056265008&fm=253&fmt=auto?w=1280&h=800"ImageDownloader.default.downloadImage(with: URL(string: url)!, options: .none) { result inswitch result{case let .success(value):UIGraphicsBeginImageContextWithOptions(CGSize(width: 150, height: 100), true, 0)value.image.draw(in: CGRect(origin: .zero, size: CGSize(width: 150, height: 100)))let image = UIGraphicsGetImageFromCurrentImageContext()UIGraphicsEndImageContext()DispatchQueue.main.async {cell.contentView.layer.contents = image?.cgImage}default:break}}}return cell}

以上使用了自己的方式进行图片解码,之所以如此是因为在如果直接加载图片在iOS中就会强制图片解码,相对而言图片解码相当耗时,现在我们将图片解码放在异步延迟处理,然后等解码完成后再进行加载,这样的好处就是不会阻塞主线程。
实验结果
如果我们加载的图片更大,超过了一整屏幕,这时候我们可以使用CATiledLayer,这是因为它做到了异步的按块的渲染。
先来看看它的注释,以下。

/* This is a subclass of CALayer providing a way to asynchronously* provide tiles of the layer's content, potentially cached at multiple* levels of detail.** As more data is required by the renderer, the layer's* -drawInContext: method is called on one or more background threads* to supply the drawing operations to fill in one tile of data. The* clip bounds and CTM of the drawing context can be used to determine* the bounds and resolution of the tile being requested.** Regions of the layer may be invalidated using the usual* -setNeedsDisplayInRect: method. However update will be asynchronous,* i.e. the next display update will most likely not contain the* changes, but a future update will.** Note: do not attempt to directly modify the `contents' property of* an CATiledLayer object - doing so will effectively turn it into a* regular CALayer. */@available(iOS 2.0, *)
open class CATiledLayer : CALayer
-drawInContext: method is called on one or more background threads to supply the drawing operations to fill in one tile of data.

可以在多个后台线程上调用进行绘图。

-setNeedsDisplayInRect: method. However update will be asynchronous,  i.e. the next display update will most likely not contain the changes, but a future update will.

不仅异步还可以做到局部渲染。
那么除此之外,还有其他的手段进行优化吗?
我们来看看NSCache,以下。

@available(iOS 4.0, *)
open class NSCache<KeyType, ObjectType> : NSObject where KeyType : AnyObject, ObjectType : AnyObject {open var name: Stringunowned(unsafe) open var delegate: (any NSCacheDelegate)?open func object(forKey key: KeyType) -> ObjectType?open func setObject(_ obj: ObjectType, forKey key: KeyType) // 0 costopen func setObject(_ obj: ObjectType, forKey key: KeyType, cost g: Int)open func removeObject(forKey key: KeyType)open func removeAllObjects()open var totalCostLimit: Int // limits are imprecise/not strictopen var countLimit: Int // limits are imprecise/not strictopen var evictsObjectsWithDiscardedContent: Bool
}@available(*, unavailable)
extension NSCache : @unchecked Sendable {
}public protocol NSCacheDelegate : NSObjectProtocol {@available(iOS 4.0, *)optional func cache(_ cache: NSCache<AnyObject, AnyObject>, willEvictObject obj: Any)
}

还可以将图片加入缓存,然后在需要使用的时候直接从缓存中取出,NSCache可以自动进行缓存管理,它做了func didReceiveMemoryWarning()的应对处理。
图片的加载优化目的是利用更多空闲资源和时间,在激活时更迅速的执行加载过程,比如在列表停止滚动时或者RunLoop休眠时异步加载,异步对图片解码,利用好缓存,在内存警告时及时释放内存,最后渲染时直接渲染。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/780687.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot实现数据库的加解密

项目地址 https://github.com/Chenchicheng/spring-ibatis-encryption 功能说明 支持使用注解的方式目标类进行加解密支持同一个类多个字段分别使用不同的加密方式支持自定义加密方法 本地调试 pull代码到本地&#xff0c;更换application.yml中的数据库用户名和密码&…

.NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案

目录(结尾附加项目代码资源地址) 引言&#xff1a; 1. SAGA事务模式 2. 拆分为子事务 3. 失败回滚 4. 如何做补偿 4.1 失败的分支是否需要补偿 5. 异常 6. 异常与子事务屏障 6.1 NPC的挑战 6.2 现有方案的问题 6.3 子事务屏障 6.4 原理 7. 更多高级场景 7.1 部分…

vue3+threejs新手从零开发卡牌游戏(二十二):添加己方游戏流程(先后手、抽牌、主要阶段、战斗阶段、结束阶段)

首先在utils/common.ts里定义一些流程相关的变量&#xff1a; const flow ref([ // 游戏流程{name: "抽卡阶段"},{name: "主要阶段"},{name: "战斗阶段"},{name: "结束阶段"}])const flowIndex ref(0) // 当前流程const currentPla…

[C++初阶] 爱上C++ : 与C++的第一次约会

&#x1f525;个人主页&#xff1a;guoguoqiang &#x1f525;专栏&#xff1a;我与C的爱恋 本篇内容带大家浅浅的了解一下C中的命名空间。 在c中&#xff0c;名称&#xff08;name&#xff09;可以是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大&#xff0c;名称…

什么是gif? 如何把视频格式转成gif动图格式?展现动图的魅力

一&#xff0c;什么是gif格式 gif是一种位图图形文件格式&#xff0c;主要用于显示索引彩色图像。gif格式在1987年由CompuServe公司开发&#xff0c;它采用LZW&#xff08;Lempel-Ziv-Welch&#xff09;无损压缩算法&#xff0c;这种算法可以有效地减少图像文件在网络上传…

在.Net6中用gdal实现第一个功能

目录 一、创建.NET6的控制台应用程序 二、加载Gdal插件 三、编写程序 一、创建.NET6的控制台应用程序 二、加载Gdal插件 Gdal的资源可以经过NuGet包引入。右键单击项目名称&#xff0c;然后选择 "Manage NuGet Packages"&#xff08;管理 NuGet 包&#xff09;。N…

【C++】 vector 数组/向量

文章目录 【 1. vector 的声明与初始化 】1.1 vector 的声明1.2 vector 的初始化1.2.1 构造一个空的 vector1.2.2 指定数量初值的方式初始化 vector1.2.3 迭代器的方式初始化1.2.4 构造一个相同的 vector 【 2. vector 的相关操作 】2.1 插入元素2.1.1 在vector的末尾插入新元素…

蚂蚁新村3.30答案:“秀女拈针锦线长,纤纤玉指领馨香”说的是哪一项非遗技艺

蚂蚁新村是一个虚拟社区。在这个虚拟社区中&#xff0c;用户可以参与各种活动&#xff0c;比如生产能量豆、做慈善捐赠等。同时&#xff0c;蚂蚁新村也提供了一些知识问答环节&#xff0c;用户在参与的过程中可以增进知识。这些问答内容往往涉及广泛的主题&#xff0c;如文化、…

iOS - Runtime - Class-方法缓存(cache_t)

文章目录 iOS - Runtime - Class-方法缓存(cache_t)1. 散列表的存取值 iOS - Runtime - Class-方法缓存(cache_t) Class内部结构中有个方法缓存&#xff08;cache_t&#xff09;&#xff0c;用散列表&#xff08;哈希表&#xff09;来缓存曾经调用过的方法&#xff0c;可以提高…

Python3:ModuleNotFoundError: No module named ‘elftools‘

问题背景 问题 ModuleNotFoundError: No module named ‘elftools’ 解决方法 pip3 install pyelftools 成功&#xff01;&#xff01;&#xff01;

YPay源支付V7开源版

YPay_V7版本即将停止维护更新&#xff0c;同时我们将开放最新版开源代码供学习和参考。虽然首批阶段的【function_8.1.php文件是加密的】&#xff0c;但授权已经除去&#xff0c;该代码将在新版YPay上线时开放给大家。我们也会定期进行迭代更新&#xff0c;随后将创建对应仓库&…

【QT学习】1.qt初识,创建qt工程,使用按钮,第一个交互按钮

1.初识qt--》qt是个框架&#xff0c;不是语言 1.学习路径 一 QT简介 &#xff0c;QTCreator &#xff0c;QT工程 &#xff0c;QT的第一个程序&#xff0c;类&#xff0c;组件 二 信号与槽 三 对话框 四 QT Desiner 控件 布局 样式 五 事件 六 GUI绘图 七 文件 八 …

解决 linux 服务器 java 命令不生效问题

在Linux系统中&#xff0c;当你安装Java并设置了JAVA_HOME环境变量后&#xff0c;你可能需要使用source /etc/profile命令来使Java命令生效。这是因为/etc/profile是一个系统级的配置文件&#xff0c;它包含了系统的全局环境变量设置。 但是需要注意的是&#xff0c;source /e…

使用C语言实现Linux下的并发Http服务器

使用C语言实现Linux下的并发Http服务器 文章目录 使用C语言实现Linux下的并发Http服务器先备知识Http协议请求格式&#xff1a;客户端请求服务端响应 Demo 实现Mini的Http服务器流程接收Http请求实现按行读取请求头部请求头部的结束 解析请求响应请求读取文件&#xff08;http需…

品质领航,流量赋能,2024喜尔康浙江省经销商培训会在喜尔康总部成功举行

3月29日&#xff0c;以“新零售、新流量、新风口”为主题的2024喜尔康浙江省经销商培训会在喜尔康总部正式开始举办。活动旨在智能新时代赋能经销商伙伴&#xff0c;通过抓住行业智能化风口&#xff0c;实现喜尔康与经销商的共赢&#xff0c;决胜未来新零售商机。 喜尔康始终致…

Charles for Mac 强大的网络调试工具

Charles for Mac是一款功能强大的网络调试工具&#xff0c;可以帮助开发人员和测试人员更轻松地进行网络通信测试和调试。以下是一些Charles for Mac的主要特点&#xff1a; 软件下载&#xff1a;Charles for Mac 4.6.6注册激活版 流量截获&#xff1a;Charles可以截获和分析通…

nuxt学习

一、遇到的问题 1、nuxt初始化失败问题解决方案 使用npm和pnpm初始化都失败 原因&#xff1a;主机连不上DNS服务器 解决方案 Step1: 打开文件夹 Windows:路径&#xff1a;C:\Windows\System32\drivers\etc Mac: 路径&#xff1a;/etc/hosts Step2: 使用记事本方式打开 …

44 el-dialog 的 appendToBody 属性, 导致 vue 响应式失效

前言 我们经常会碰到 一些 模型和视图 不同步的问题 通常意义上 主要的问题为 列表的某响应式数据更新着更新着 后面就变成非响应式对象了, 然后 就造成了 数据一直在更新, 但是 视图的渲染后面就未渲染了, 这是一个由于 模型上的问题 导致的数据的不在响应式更新 又或者 是…

【倪琴神品品鉴】全新倪诗韵神品级古琴

倪琴朱砂神品仲尼&#xff0c;仅此放漏一张&#xff1b;龙池侧签海门倪诗韵制&#xff0c;雁足上方刻“雷音琴坊”方章&#xff0c;凤沼下方有随形章“神品”二字&#xff1b;老木材纹理竖直&#xff0c;共振良好&#xff0c;是难得的佳器&#xff1b;附带倪老师亲笔签名收藏证…

图扑数字孪生智慧城市,综合治理一屏统览

现代城市作为一个复杂系统&#xff0c;牵一发而动全身&#xff0c;城市化进程中产生新的矛盾和社会问题都会影响整个城市系统的正常运转。智慧城市是应对这些问题的策略之一。领导曾在中央城市工作会议上指出&#xff0c;城市工作要树立系统思维&#xff0c;从构成城市诸多要素…