获得徽章 0
#每天一个知识点#
当我们在谈论图片解码的时候,我们在谈什么?


我们常见的图片 PNG JPEG 文件,实际上是压缩过的,为了减少空间占用和带宽消耗嘛。
那么屏幕要显示这些图片就必须经过解压,拿到完整的位图数据(像素数组,每个元素代表图片上的一个点)。
在 iOS 开发中呢,解码分四步走:
1. 根据 NSData 对象(从文件读取生成)创建一个 source 对象,source 是待解码数据的输入,解码的过程都是通过它来完成
2. 从 source 中读取图像信息,比如图像格式、元信息等,下一步解码要用
3. 调用解码库解码 source,苹果自带的就是 ImageIO,接口是CGImageSourceCreateImageAtIndex,得到一个 CGImageRef
4. 根据解码后的数据生成 UIImage,它是可以显示的图像对象。释放资源

动态图片的解码也差不多,只是将一帧帧图片都解码生成 UIImage,后面再把所有 UIImage 合并生成一个 AnimatedImage(还是 UIImage 类型)

第三方解码器解码的过程又有所不同,就是不用 source 了,重点放在 BitMap 的获取上
1. 先获取到图像的 BitMap 数据(像素数组)
2. 根据 BitMap 生成 CGImage 数据
3. 重绘。把 CGImage 绘制到一个上下文里,这一步是因为CALayer 和 UIImageView 渲染的时候要求的色彩限定,为了减少渲染消耗和内存消耗,这里重新绘制一波
4. 然后根据上下文 context 生成 UIImage。(当然,也要清理资源)[可怜]
展开
评论
SDWebimage 如何设计缓存?

memory + disk 内存+磁盘双缓存。
获取图片前先查找这两个缓存里有没有,内存里没有就去磁盘找,磁盘里没有才下载,如果磁盘里有,那么就会把磁盘缓存 copy 到内存缓存 _syncDiskToMemoryWithImage

什么时候添加缓存?
图片下载后,根据缓存策略(默认是都存)
把 UIImage 存到NSCache 中
同时也会把压缩格式的 图片存到本地沙盒

什么时候清理缓存?
内存:收到内存预警时,删除所有内存
磁盘:App 退出或者进入后台时,会检查当前缓存是否超出了maxDiskSize (默认无限额,需要开发者手动设置),或者存储的缓存数据是否过期(保质期默认 7 天 kDefaultCacheMaxDiskAge)。如果超出了,那也不是删除全部,而是把图片删除到 maxDiskSize 的一半

很合理,收工的时候清理一下,还手机一个干净整洁的空间
(真的很舒服啊 SDWebimage 的源码看着,虽然看不太懂,但是整洁、齐全、有注释,结构合理)


#每天一个知识点#
展开
评论
多线程中的栅栏 barrier 是什么?

先说点背景知识,iOS 开发中经常会用队列来调度 block 的执行,并发队列支持多个 block 同时执行(只要开多几个线程),串行队列让 block 只能一个一个执行,一个 block 执行完,另一个 block 才能开始。

栅栏函数就是用在并发队列中的,为的就是在并发队列中拿一点先后顺序。因为栅栏函数分配的 block A,会等这个队列中其他 block 执行完,然后到 blockA 单独执行,它执行完,然后才是队列其他中排在它后面的 block 执行。
这就相当于在无序的并发队列中拿到了一点「顺序」。

这么做的原因就是最大程度利用系统性能,顺序不敏感的 block 直接放进去,开多几个线程一起执行,对顺序有要求的 block 我就用栅栏函数放进去

图为 AFNetworking 图片下载器中添加图片缓存的逻辑,就用到了 barrier 来保证「添加图片」和「删除图片」的先后顺序[呲牙]

#每天一个知识点#
展开
跳入西湖于2024-03-22 10:46发布的图片
评论
下一页
个人成就
文章被点赞 80
文章被阅读 12,688
掘力值 491
收藏集
3
关注标签
0
加入于