您当前所在位置:首页>>CF活动大全

cf免费领取cf点有哪些明明是bug,却被说成是feature的例子?

来源:CF活动助手|发布时间:2022-10-28 11:10:43|浏览次数:3

cf手机游戏助手

一、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% 左右就会被杀死进程。

Tips:不同手机由于内存和屏幕不一样,内存超限 App 发生 Crash 的条件不一样,其中iPhone 6P是最容易 Crash 的,因为它有 5.5 寸的屏幕,却只有1G 内存,加载 Assets.xcassets 图片时会加载 3x 图片,同一张网络图片

cf活动助手显示不能排位

,UIImageView 布局一般会按照比例放大,大屏手机图片会放大,解码后占用内存也就更大。

1.4、解决方案

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

1.5、iOS图片解码

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

cf领取98

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

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

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

图片解码后会占用多少内存呢?其实这个很好计算,苹果手机采用 24 位真彩色显示图像,也就是 24bit(3 字节,RGB 红绿蓝三原色分别占用 8bit,每个颜色有 256 种状态),如果是不包含 Alpha 通道(透明度)的 RGB 图片,那每个像素占用的就是 3 字节,15000px*15000px*3Byte = 644MB,如果是包含透明度的 RGBA 图片,则为 15000px*15000px*4Byte = 858MB,如图2所示,加载一张长和宽 15000px 的图片,内存暴增 858MB。

1.7、图片缩放最优选择

最常用的图片缩放方法是使用CGContext的UIGraphicsGetImageFromCurrentImageContext方法对图片进行裁剪缩放,能够满足大部分需求。但如果是处理多张大图,这时候就需要优化缩放速度了,可通过 Image I/O 框架对图片进行缩放,在工程中添加Image I/O Framework,然后在需要使用的地方import即可,示例代码如下:

//maxPixelSize MUST BE avalid value. + (UIImage *)thumbImageFromLargeFile:(NSString *)filePath withConfirmedMaxPixelSize:(CGFloat)maxPixelSize { // Create the image source (from path) CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:filePath], NULL); // Create thumbnail options CFDictionaryRef options = (__bridge CFDictionaryRef) @{ (id) kCGImageSourceCreateThumbnailWithTransform : @YES, (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES, (id) kCGImageSourceThumbnailMaxPixelSize : @(maxPixelSize) }; // Generate thethumbnailCGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options); CFRelease(src); UIImage *image = [[UIImage alloc] initWithCGImage:thumbnail]; CFRelease(thumbnail); return image; } 复制代码

cf手游准心助手下载

©版权所有 2015-2023 CF活动助手一键领取 辽ICP备2021000370号-5 XML地图 TXT地图
友情链接: CF活动助手一键领取