iOS面试题锦集

news2025/1/16 15:55:18

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.coloradmin.cn/o/1519140.html

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

相关文章

Nuxt3配置本地访问链接 -- Network: use --host to expose

这种表示没有在线访问本地链接 在nuxt.config.ts里面 export default defineNuxtConfig({// 配置本地访问链接devServer: {host: 192.168.1.41,//自己电脑的Ipport: 3000,}, }) 复制到浏览器就可以访问,给别人使用必须是局域网,同一个网络

FreeRTOS学习第10篇--队列使用示例

FreeRTOS学习第10篇–队列使用示例 本文目标:FreeRTOS学习第10篇–队列使用示例 按照本文的描述,可以进行简单的使用队列。 本文实验条件:拥有C语言基础,装有编译和集成的开发环境,比如:Keil uVision5 …

独家授权!广东盈世获网易邮箱反垃圾服务的独家授权,邮件反垃圾更全面

近日,广东盈世计算机科技有限公司(以下简称“Coremail”)成功获得了网易(杭州)网络有限公司(以下简称“网易”)授予的网易邮箱反垃圾服务独家使用权。这一授权使得Coremail能够在邮件安全产品上…

创建出色用户界面的五个关键技巧,助您实现用户体验的提升!

易于理解的用户界面通常很容易阅读,它们有美丽的布局和完美的颜色组合,通过提供简单和直观的选项,告诉用户应用程序可以做什么。 因此,在创建用户界面时,(UI)当时,UI设计师往往优先…

人大金仓大小写敏感处理

人大金仓安装的时候,不管是否选择大小写敏感;查询的时候加和不加双引号,查询出来的都是小写 针对人大金仓大小写,我们实际引用全是大写的情况,解决方案如下 添加配置,将查询结果全都转成大写 1、本地打开…

FastAPI 是什么?深入解析

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建基于 Python 的 API。它是一个开源项目,基于 Starlette 和 Pydantic 库构建而成,提供了强大的功能和高效的性能。 FastAPI 官网地址:fastapi.tiango…

npm WARN config init.license Use `--init-license` instead.

背景:近期升级本地node版本(v14.15.4 --> v18.19.1),npm -v报警 npm WARN config init.license Use --init-license instead. npm WARN config init.author.name Use --init-author-name instead. 分析: npm高版本…

使用pgadmin备份数据库

本人菜鸟, 在使用PostgreSQL数据库的时候, 经常会用到这个pgadmin的可视化工具 这个工具提供了很简单的备份和还原方法, 操作如下 备份 (1)首先鼠标右键选中你要备份的数据库,如图的 LBSYS (2)然后点击 backup (…

【SVG】前端-不依靠第三方包怎么画连线???

如何用SVG实现连线功能 在Web开发中,我们经常会遇到需要在页面上绘制图形或者实现一些图形交互的场景。SVG(Scalable Vector Graphics)作为一种用于描述二维图形的XML标记语言,在这方面提供了极大的便利。本文将以一个具体的例子…

WordPress网站启用cloudflare的CDN加速后,网站出现多重定向无法访问

这是一个使用Hostease的Linux虚拟主机的客户反馈的问题,Hostease的虚拟主机使用的也是cPanel面板,客户使用的是cPanel的softaculous安装的WordPress,但是在安装完成后,并且解析了域名之后,发现网站无法访问&#xff0c…

高校实验室科研仪器开放共享存在的问题及对策建议

随着科技的迅速发展和高校科研水平的提高,高校实验室科研仪器的开放共享已经成为推动科研进步和创新发展的重要手段。然而,在实际操作中,我们也面临着诸多问题和挑战。本文将分析高校实验室科研仪器开放共享存在的问题,并提出相应…

java复健-接口的开发及参数校验

遇到的问题以及解决方案 Q1. 开发接口的流程 A1: 明确需求阅读接口文档思路分析开发测试 Q2. 开发时用到的技术 A2: LomBok:Data,自动为我们的实体类创建构造方法,set(),get&am…

8. C++对象模型

1. 普通类对象是什么布局? struct Base {Base() default;~Base() default;void Func() {}int a;int b; };int main() {Base a;return 0; }2. 带虚函数的类对象是什么布局? struct Base {Base() default;virtual ~Base() default;void FuncA() {}v…

Uni-app跟学笔记(五):uni-ui组件库的使用、项目打包(小程序、h5、APP)

文章目录 1)uni-ui组件库的使用2)项目打包1:微信小程序打包2:h5打包3:安卓打包 本博客为 uni-app 此门课的跟学笔记,目的是便于个人复习和对知识快速索引,源码素材可在均可在视频评论区找到 1&a…

Vue2 父子组件某一属性的双向绑定

原本&#xff1a;父组件使用props传值给孩子组件初始化&#xff0c;触发事件子组件使用$emit传值给父组件&#xff0c;很麻烦后来&#xff1a;使用computed和$event例子代码&#xff1a; <template><div class"box">grandpa <el-input v-model"…

‍❄️Unity 官方免费资源大放送!森林、沙漠、北极等 350+逼真的自然纹理 Megapack等你来拿

&#x1f333;350自然纹理 Megapack&#xff0c;免费获取&#xff01;&#x1f381; 你是否热爱游戏开发&#xff0c;却被昂贵的资源库所困扰&#xff1f;你是否渴望创造出令人惊叹的自然场景&#xff0c;却被有限的纹理素材所束缚&#xff1f;如果你的答案是肯定的&#xff0c…

01- Java概述

第1章 Java概述 1.1 Java语言发展历史&#xff08;记关键点&#xff09; Java诞生于SUN&#xff08;Stanford University Network&#xff09;&#xff0c;09年SUN被Oracle&#xff08;甲骨文&#xff09;收购。 Java之父是詹姆斯.高斯林(James Gosling)。 1996年发布JDK1.…

分布式思想

1、单体架构设计存在的问题 传统项目采用单体架构设计,虽然可以在一定的程度上解决企业问题,但是如果功能模块众多,并且将来需要二次开发.由于模块都是部署到同一台tomcat服务器中,如果其中某个模块代码出现了问题,将直接影响整个tomcat服务器运行. 这样的设计耦合性太高.不便…

【软件测试基础篇】第二节.黑盒测试中常见方法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言⼀、等价类法&#xff08;解决穷举问题&#xff09;二、边界值法&#xff08;解决边界限制问题&#xff09;三、正交表法&#xff08;解决多条件依赖问题&#…

Docker学习之镜像管理(超详解析)

Docker镜像生命周期&#xff08;可以把docker镜像理解为虚拟机镜像&#xff09; 实验内容&#xff1a; 搜索官方仓库镜像 [rootlocalhost ~]# docker search busybox //以查找busybox为例 搜索说明&#xff1a;name镜像名称 description镜像说明 stars点赞数量 official…