iOS面试题锦集

1. 问:一张图片所占内存大小跟什么有关?

图片所占内存大小,与图片的宽高有关

我们平时看到的png、jpg、webp这些图片格式,其实都是图片压缩格式。通过对应的算法来优化了大小以节省网络传输与本地保存所需的资源。
但是当我们加载图片到内存中将要显示出来的时候是不能使用压缩格式,这样就不能显示图片了。

计算机依赖每一个像素点中的数据来显示图片。
例如iOS中的UIImange的每个像素点是由red+green+blue 三原色在加上alpha透明度组成的。
三原色每一个的范围在0 ~ 255所以需要1个字节来存储一个值的大小。
那么一个像素点的颜色就需要3个字节
再加上需要alpha的大小,alpha的范围是0~100 也是以1个字节来存储的。
所以一个像素点就需要4个字节来存储

疑问:
像素一定是RGB表示?必须是占4个字节?
像素会不会其他格式表示,从而造成所占字节数不同?

在这里插入图片描述

这样算来,一个image的size为100100,每个像素点占4个字节,那么
该图片的内存占用为:100
1004byte = 40000btye = 40001024KB

测试:

取一个图片,其大小是750x844
在这里插入图片描述

在这里插入图片描述

- (void)testImageSize
{UIImageView *imageView = [[UIImageView alloc] init];imageView.frame = CGRectMake(100, 100, 100, 100);imageView.image = [UIImage imageNamed:@"yz_life_share_gift_top_bg_image_2"];[self.view addSubview:imageView];//获取//The width, in pixels, of the specified bitmap image (or image mask).//指定位图图像(或图像掩码)的宽度(以像素为单位)。CGFloat imageWidth = CGImageGetWidth(imageView.image.CGImage);CGFloat imageHeight = CGImageGetHeight(imageView.image.CGImage);CGFloat imageMemorySize = imageHeight * imageWidth * 4 /1024/1024;NSLog(@"%f, %f, %f", imageWidth, imageHeight, imageMemorySize);//750.000000, 844.000000, 2.414703//或者//The number of bytes used in memory for each row of the specified bitmap image (or image mask).//指定位图图像(或图像掩码)的每一行在内存中使用的字节数。CGFloat bytesPerRow = CGImageGetBytesPerRow(imageView.image.CGImage);CGFloat imageMemorySize2 = imageHeight * bytesPerRow/1024/1024;NSLog(@"%f, %f, %f", bytesPerRow, imageHeight, imageMemorySize2);//3000.000000, 844.000000, 2.414703
}

也就是,一张11KB大小的图片,在内存中占用的内存大小是2.414703M

还是蛮大的

图片的大小?

首先,宽高,是指的图片本身的宽高,而不是mageView被设置的size

而图片的大小,可以用 单位为厘米 去测量,也可以用 单位为像素 去测量
比如100cm * 100cm大小的图片,其换算成像素为单位,并不是100px * 100px

本文章里,所讲的图片的大小,其实是以像素为单位的图片的大小

iOS uiimage内存占用大小计算

2. 问:为什么图片占用这么大的内存,而不是图片的原始大小?

这就要从图片格式来说,我们通常用的图片格式如:png和jpeg等,这些格式的图片都是压缩的位图格式,不能直接渲染展示在屏幕上,所以就需要在渲染到屏幕之前,需要将图片解压缩,得到图片的原始像素数据,过程如下:
在这里插入图片描述
即:Data Buffer、Image Buffer、Frame Buffer
Data Buffer 是存储在内存中的原始数据,图像可以使用不同的格式保存,如 jpg、png。是Image 的文件内容。
Image Buffer 是图像在内存中的存在方式,用于存放图像具体素点信息。Image Buffer 的大小和图像的大小成正比。
Frame Buffer 和 Image Buffer 内容相同,不过其存储在 vRAM(video RAM)中,而 Image Buffer 存储在 RAM 中。
解码就是从 Data Buffer 生成 Image Buffer 的过程。Image Buffer 会占用带宽上传到 GPU 成为 Frame Buffer,最后GPU负责使用 Frame Buffer用于更新显示区域。

3. 问:如何避免图片占用内存过大的问题呢?

方法一:

使用[UIImage imageNamed:@""];这种方式加载图片的话,图片会缓存在内存里面,不被释放
如果遇到频率使用低的图片、图片大的图片,建议使用[UIImage imageWithContentsOfFile:nil];这种方式加载图片

使用imageName:加载图片

  • 加载到内存当中会一直存在内存当中,(图片)不会随着对象的销毁而销毁。
  • 加载进去图片后,占用的内存归系统管理,我们是无法管理的。
  • 相同的图片是不会重复加载的
  • 加载到内存中占据的内存较大

使用imageWithContentOfFile:加载图片

  • 加载到内存中占据的内存较小
  • 相同的图片会被重复加载到内存当中
  • 加载的图片会随着对象的销毁而销毁

[UIImage imageNamed:]加载图片,与imageWithContentOfFile:加载图片有什么区别?

方法二:

使用UIGraphicsImageRenderer的API

如果ImageView的本身就是固定的200x200,加载800x800的图片会有什么问题?
答案:载入800x800的图片用到200x200的控件上是很浪费内存。需要消耗的内存大小800x800x4bit。

解决方案:在使用前把图片调整到需要的大小

因此,我们使用UIGraphicsImageRenderer,将图片大小调整为用户自己所需要的大小,以减少内存的使用

UIImage *image = [UIImage imageNamed:@"yz_life_share_gift_top_bg_image_2"];
//调用,或者直接传image.size.width
image = [self resiImage:image size:CGSizeMake(100, 100)];
imageView.image = image;//方法
- (UIImage*)resiImage:(UIImage *)image size:(CGSize)size{UIGraphicsImageRenderer *re = [[UIGraphicsImageRenderer alloc]initWithSize:size];return [re imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {[image drawInRect:CGRectMake(0, 0, size.width, size.height)];}];
}

iOS Image 内存优化
UIGraphicsImageRenderer图片渲染优化


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

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

相关文章

Adobe PDF背景设置护眼模式,缓解眼部疲劳

一、背景 在用Adobe PDF看论文时,默认的白色背景看久了,眼睛会特别疲劳,下面介绍如何设置背景为护眼模式。 二、设置PDF为护眼模式 使用Adobe Acrobat Pro DC打开任意PDF文件,在上方工具栏选择“编辑”,在下拉菜单栏…

塑料工厂5G智能制造数字孪生可视化平台,推进塑料行业数字化转型

塑料工厂5G智能制造数字孪生可视化平台,推进塑料行业数字化转型。塑料制造行业作为重要的工业领域,亟需借助这一平台实现产业升级与转型,以适应市场的变化和提高生产效率。传统的塑料制造过程往往存在生产效率低下、资源浪费、环境污染等问题…

数据结构 之 队列(Queue)

​​​​​​​ 🎉欢迎大家观看AUGENSTERN_dc的文章(o゜▽゜)o☆✨✨ 🎉感谢各位读者在百忙之中抽出时间来垂阅我的文章,我会尽我所能向的大家分享我的知识和经验📖 🎉希望我们在一篇篇的文章中能够共同进步&#xff0…

HTML + CSS 高频考点之 - 定位

简述: 补充固定定位也会脱离文档流、不会占据原先位置 1、什么是文档流 文档流是指HTML文档中元素排列的规律和顺序。在网页中,元素按照其在HTML文档中出现的顺序依次排列,这种排列方式被称为文档流。文档流决定了元素在页面上的位置和互相之…

【Docker】 ubuntu18.04编译时内存不足需要使用临时交换分区解决“c++: internal compiler error“错误

【Docker】 ubuntu18.04编译时内存不足需要使用临时交换分区解决"c: internal compiler error"错误 问题描述 安装独立功能包时编译不成功,出现 “c: internal compiler error: Killed(program cciplus)” 错误。 解决方案 出现这个问题的原因大概率是…

力扣题目训练(21)

2024年2月14日力扣题目训练 2024年2月14日力扣题目训练605. 种花问题617. 合并二叉树628. 三个数的最大乘积289. 生命游戏299. 猜数字游戏149. 直线上最多的点数 2024年2月14日力扣题目训练 2024年2月14日第二十一天编程训练,今天主要是进行一些题训练,…

Docker安装蜜罐Hfish

前言 无意中发现公司的一台服务器被爆破,修改了密码,为了确定内网是否安装需要搭建一个蜜罐来看一下是否存在隐患。 如何安装Docker,请查看我另一篇文章 https://blog.csdn.net/l1677516854/article/details/136751211 一、拉取镜像 dock…

dockers拉取MySQL及Redis并挂载文件

目录 一 . MySQL拉取 1、进入 MySQL 容器内部。 2、登录 MySQL。 3、修改远程连接 4、刷新 二 . Redis拉取 1 . redis/conf中新建文件redis.conf,内容如下: 2 . 容器运行 一 . MySQL拉取 docker run -d --restartalways --name mysql \ -v /…

HTML、XHTML和HTML5系列对比

目录 HTML HTML的优点: HTML的缺点: 应用场景: XHTML XHTML的优点: XHTML的缺点: 应用场景: HTML5 HTML5的优点: HTML5的缺点: 应用场景: 回首发现&#xff0…

算法刷题Day11 | 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

目录 0 引言1 有效的括号1.1 我的解题 2 删除字符串中的所有相邻重复项2.1 我的解题 3 逆波兰表达式求值3.1 我的解题 🙋‍♂️ 作者:海码007📜 专栏:算法专栏💥 标题:❣️ 寄语:书到用时方恨少…

Spring中使用内置的tomcat容器启动后自动退出问题解决方法

在Spring中使用内置的tomcat 启动后自动退出 退出代码为0 且不报任务错误的解决方法. 日志如下: Connected to the target VM, address: 127.0.0.1:51129, transport: socket 三月 15, 2024 11:55:00 下午 org.apache.coyote.AbstractProtocol init 信息: Initializing Proto…

Linux下安装多个nodejs并映射Jenkins

背景 需要Jenkins中切换多个Node,比如nodejs16和nodesjs18,所以在宿主机按照好这两个版本,然后再映射到Jenkins容器中 步骤 1.下载地址 https://nodejs.org/dist/ 放到 cd /opt/soft/2.解压 tar -xzvf node-v16.20.0-linux-x64.tar.gz tar -xzvf n…