记一些印象深刻的 Bug

一、iOS 加载超大尺寸图片 Crash 的调研及解决方案

1.1、问题描述

前段时间遇到一个工单,客户反馈,只要进入订单列表界面 1~2 秒,客户端就会 Crash,订单列表界面示意如下:

1.2、问题分析

由于是客户投诉的 Bug,没有 Debug 信息,先猜测各种情况,数组越界/后台传 nil 值/内存泄露/ KVO 赋未定义值等等;然而经过仔细分析模拟逐个排除了上述可能,仍查找不到 Crash 原因,百思不得其解。

排除了代码的问题,只有可能是数据问题了,猜测是异常的图片/数据解析出现的问题,于是抽取用户订单数据分析,发现有 2 张尺寸非常大的 JPEG 图片,尺寸达到了 15000*8000 的像素,瞬间想明白了怎么回事,像素总量达到了一亿两千万,猜测是图片解压缩到内存后占用内存过大,导致系统内存紧张,因此系统杀死了 App 进程。

1.3、问题验证

验证是否因大尺寸图片引起的错误。验证过程如下:

写一个类似上面订单列表的 Demo,点击 Cell 逐个加载大图图片,测试用的手机为 iPhone 7P,图片尺寸为(15000px*15000px),点击加载第二张图片就发生了 Crash,一般情况下,APP 占用系统内存 60% 左右就会被杀死进程。iPhone 7P 加载大图后的内存截图如下:

Tips: 不同手机由于内存和屏幕不一样,内存超限 App 发生 Crash 的条件不一样,其中 iPhone 6P 是最容易 Crash 的,因为它有 5.5 寸的屏幕,却只有 1G 内存,加载 Assets.xcassets 图片时会加载 3x 图片,同一张网络图片,UIImageView 布局一般会按照比例放大,大屏手机图片会放大,解码后占用内存也就更大。

1.4、解决方案

  • 约定大于配置,上传图片也要遵守一定的约定。 基于 SDWebImage/YYImage 等第三方库加载超大图引起的崩溃,可通过修改源码解决,但不建议这样做;修改源码可能会引起其他 Bug,而且大图毕竟是少数,没必要对所有图片都进行判断,个别大图单独处理即可。按照一定约定,通过管理平台限定上传图片尺寸大小,增加 APP 流畅度的同时,还能减少用户流量损失,此为最佳方案。
  • 缩放图片尺寸。 如果是展示整张图片,不需要展示图片细节,受限于屏幕分辨率,太大尺寸的图片是没有意义的;如果需要做类似于图片浏览器,可对图片进行放大缩小操作的需求,大图预览的时候可加载缩略图,展示的时候切片处理。

1.5、iOS 图片解码

我们常见的图片格式例如 PNG/JPG/GIF 等格式都属于图像压缩格式,解压为位图后占用的内存会非常大。

假设 iOS 系统从磁盘加载一张图片,首先将文件数据从磁盘读到内存中,此时在内存中仍旧是压缩格式,只有在需要的时机,才会把图片解码为无压缩的位图格式,最后 Core Animation 使用未压缩的位图数据渲染 UIImageView 的图层。

将压缩的图片数据解码成未压缩的位图形式,这是一个耗时的 CPU 操作,SDWebimage/YYImage 等第三方框架一般都会提前异步强制解码图片,保证了 UI 界面的流畅性。

1.6、图片解码占用内存计算

图片解码后会占用多少内存呢?其实这个很好计算,苹果手机采用 24 位真彩色显示图像,也就是 24bi

  • 3
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值