iOS经典面试题总结--内存管理

2023-10-26

我根据自己的情况做了一下总结,答案是我总结的,如有答的不好的地方,希望批评指正以及交流,谢谢!

内存管理

1.什么是ARC?

ARC是automatic reference counting自动引用计数,在程序编译时自动加入retain/release。在对象被创建时retain count+1,在对象被release时count-1,当count=0时,销毁对象。程序中加入autoreleasepool对象会由系统自动加上autorelease方法,如果该对象引用计数为0,则销毁。那么ARC是为了解决MRC手动管理内存存在的一些而诞生的。

MRC下内存管理的缺点:

释放一个堆内存时,首先要确定指向这个堆空间的指针都被release了。(避免提前释放)

释放指针指向的堆空间,首先要确定哪些指向同一个堆,这些指针只能释放一次。(避免释放多次,造成内存泄露)

模块化操作时,对象可能被多个模块创建和使用,不能确定最后由谁释放

多线程操作时,不确定哪个线程最后使用完毕。

虽然ARC给我们编程带来的很多好多,但也可能出现内存泄露。如下面两种情况:

循环参照:A有个属性参照B,B有个属性参照A,如果都是strong参照的话,两个对象都无法释放。

死循环:如果有个ViewController中有无限循环,也会导致即使ViewController对应的view消失了,ViewController也不能释放。

2.block一般用那个关键字修饰,为什么?

block一般使用copy关键之进行修饰,block使用copy是从MRC遗留下来的“传统”,在MRC中,方法内容的block是在栈区的,使用copy可以把它放到堆区。但在ARC中写不写都行:编译器自动对block进行了copy操作。

3.用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?

答:用@property声明 NSString、NSArray、NSDictionary 经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。

如果我们使用是strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。

copy此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是将其“拷贝” (copy)。 当属性类型为NSString时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个NSMutableString类的实例。这个类是NSString的子类,表示一种可修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。

4.runloop、autorelease pool以及线程之间的关系。

每个线程(包含主线程)都有一个Runloop。对于每一个Runloop,系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个像callstack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每个Object会被release。

5.@property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的。

“属性”(property)有两大概念:ivar(实例变量)、存取方法(access method=getter),即@property = ivar + getter + setter。

例如下面的这个类:

@interface WBTextView :UITextView

@property (nonatomic,copy)NSString *placehold;

@property (nonatomic,copy)UIColor *placeholdColor;

@end

类完成属性的定以后,编译器会自动编写访问这些属性的方法(自动合成autosynthesis),上述代码写出来的类等效与下面的代码:

@interface WBTextView :UITextView

- (NSString *)placehold;

-(void)setPlacehold:(NSString *)placehold;

-(UIColor *)placeholdColor;

-(void)setPlaceholdColor:(UIColor *)placeholdColor;

@end

详细介绍见:http://blog.csdn.net/jasonjwl/article/details/49427377

6.分别写一个setter方法用于完成@property (nonatomic,retain)NSString *name和@property (nonatomic,copy) NSString *name

retain属性的setter方法是保留新值并释放旧值,然后更新实例变量,令其指向新值。顺序很重要。假如还未保留新值就先把旧值释放了,而且两个值又指向同一个对象,先执行的release操作就可能导致系统将此对象永久回收。

-(void)setName:(NSString *)name

{

[name retain];

[_name release];

_name = name;

}

-(void)setName:(NSString *)name

{

[_name release];

_name = [name copy];

}

7.说说assign vs weak,_block vs _weak的区别

assign适用于基本数据类型,weak是适用于NSObject对象,并且是一个弱引用。

assign其实页可以用来修饰对象,那么为什么不用它呢?因为被assign修饰的对象在释放之后,指针的地址还是存在的,也就是说指针并没有被置为nil。如果在后续内存分配中,刚才分到了这块地址,程序就会崩溃掉。而weak修饰的对象在释放之后,指针地址会被置为nil。

_block是用来修饰一个变量,这个变量就可以在block中被修改。

_block:使用_block修饰的变量在block代码块中会被retain(ARC下,MRC下不会retain)

_weak:使用_weak修饰的变量不会在block代码块中被retain

8.请说出下面代码是否有问题,如果有问题请修改?

@autoreleasepool {

for(int i=0; i[largeNumber; i++) { (因识别问题,该行代码中尖括号改为方括号代替)

Person *per = [[Person alloc] init];

[per autorelease];

}

}

内存管理的原则:如果对一个对象使用了alloc、copy、retain,那么你必须使用相应的release或者autorelease。咋一看,这道题目有alloc,也有autorelease,两者对应起来,应该没问题。但autorelease虽然会使引用计数减一,但是它并不是立即减一,它的本质功能只是把对象放到离他最近的自动释放池里。当自动释放池销毁了,才会向自动释放池中的每一个对象发送release消息。这道题的问题就在autorelease。因为largeNumber是一个很大的数,autorelease又不能使引用计数立即减一,所以在循环结束前会造成内存溢出的问题。

解决方案如下:

@autoreleasepool {

for(int i=0; i[100000; i++) { (因识别问题,该行代码中尖括号改为方括号代替)

@autoreleasepool {

Person *per = [[Person alloc] init];

[per autorelease];

}

}

}

在循环内部再加一个自动释放池,这样就能保证每创建一个对象就能及时释放。

9.请问下面代码是否有问题,如有问题请修改?

@autoreleasepool {

NSString *str = [[NSString alloc] init];

[str retain];

[str retain];

str = @"jxl";

[str release];

[str release];

[str release];

}

这道题跟第8题一样存在内存泄露问题,1.内存泄露 2.指向常量区的对象不能release。

指针变量str原本指向一块开辟的堆区空间,但是经过重新给str赋值,str的指向发生了变化,由原来指向堆区空间,到指向常量区。常量区的变量根本不需要释放,这就导致了原来开辟的堆区空间没有释放,照成内存泄露。

10.什么情况下使用weak关键字,相比assign有什么不同?什么情况使用weak关键字?

在ARC中,在有可能出现循环引用的时候,往往要通过让其中一端使用weak来解决。比如delegate代理

自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用weak,自定义控件属性一般也使用weak。

不同点:

weak此特质表明该属性定义了一种“非拥有关系”。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特性与assign一样,然而在属性所指的对象遭到推毁时,属性值也会清空。而assign的“设置方法”只会执行针对“纯量类型” (scalar type,例如 CGFloat 或 NSlnteger 等)的简单赋值操作。

assign可以用非OC对象,而weak必须用于OC对象。

11.内存管理语义(assign、strong、weak等的区别)

assign “设置方法” 只会执行针对“纯量”的简单赋值操作。

strong 此特质表明该属性定义了一种“拥有关系”。为这种属性设置新值时,设置方法会先保留新值,并释放旧值,然后再将新值设置上去。

weak 此特质表明该属性定义了一种“非拥有关系”。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似,然而在属性所指的对象遭到推毁时,属性值也会清空。

unsafe_unretained 此特质的语义和assign相同,但是它适用于“对象类型”,该特质表达一种“非拥有关系”,当目标对象遭到推毁时,属性值不会自动清空,这一点与weak有区别。

copy 此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是设置方法并不保留新值,而是将其“拷贝”。当属性类型为NSString*时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个NSMutableString类的实例。这个类是NSString的子类,表示一种可以修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变”的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的”,就应该在设置新属性值时拷贝一份。

问啊-定制化IT教育平台牛人一对一服务,有问必答,开发编程社交头条 官方网站:www.wenaaa.com

QQ群290551701 聚集很多互联网精英,技术总监,架构师,项目经理!开源技术研究,欢迎业内人士,大牛及新手有志于从事IT行业人员进入!

转载于:https://my.oschina.net/u/2394328/blog/630830

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS经典面试题总结--内存管理 的相关文章

  • 【深度学习】参数量、模型大小、显存

    对于一个深度学习神经网络来说 其通常包含很多卷积层 用于不断提取目标的特征 或对目标进行最终定位或者分类 1 数据存储精度与存储空间 在深度学习神经网络中 最常见的数据格式是float32 占4个字节 Byte 类似地 float16 占2
  • std::condition_variable

    std condition variable std condition variable 是C 11提供的条件变量 可用于同时阻塞一个线程或多个线程 一般的 生产者线程利用支持std mutex的std lock guard std un
  • 【React Hook】一文让你彻底明白何为State Hook?

    使用 State Hook 下面的例子介绍了 Hook import React useState from react function Example 声明一个叫 count 的 state 变量 const count setCoun
  • 如何解除计算机的启动项,UEFI安全启动怎么关闭 关闭UEFI启动项的方法图解

    大家都知道现在很多电脑都预装win8系统 其系统都开启了UEFI安全启动选项 然而 对于不习惯win8操作界面的朋友来说 可能就会把win8改为win7 但是我们得知道Win8改装Win7需要在BIOS下关闭UEFI选项 如果OS选项已经关
  • ctfshow-萌赛

    目录 web 签到 给她 假声赛 web 签到 很明显的命令执行漏洞 我们把前后闭合即可 payload 1 ls 1 1 cat flag 1 给她 根据题目提示很容易就想到是 git泄露 直接用gitHack扫描题目地址 git 发现存
  • 电子科技大学人工智能期末复习笔记(二):MDP与强化学习

    目录 前言 期望最大搜索 Expectimax Search 马尔科夫决策 MDP offline 超重点 先来看一个例子 基本概念 政策 Policy 折扣 Discounting 如何停止循环 价值迭代 Value Iteration
  • LeetcodeSQL入门——知识点总结(选择/排序/修改/字符串处理/正则)

    LeetcodeSQL入门 选择 排序 修改 字符串处理 选择 sql语言对于空值的判断是IS NULL或者IS NOT NULL eg 某网站包含两个表 Customers 表和 Orders 表 编写一个 SQL 查询 找出所有从不订购
  • 剑指Offer 40

    使用优先队列 将非负数变为非正数存储 结果变成非负数 class Solution public int getLeastNumbers int arr int k if k 0 return new int 0 int nums new
  • SequenceInputStream----合并流

    这个类的作用是将多个输入流合并成一个输入流 通过SequenceInputStream类包装后形成新的一个总的输入流 1 SequenceInputStream InputStream s1 InputStream s2 和Sequence
  • 差分方程与滤波的实现

    1 滤波基础知识 2 差分方程 3 IIR滤波器 1 直接I型IIR滤波器 2 直接II型IIR滤波器
  • 备战2023蓝桥国赛-移动服务

    题目描述 解析 这道题我想复杂了 一开始我是这样想的 设dp i j 表示按顺序满足到第i个请求时 最初在j号点的人到达第i个请求的位置的情况下的最小花费 state i j 表示按顺序满足到第i个请求时 最初在j号点的人到达第i个请求的位
  • Typescript 之接口 interface(详解)

    一 interface的基本含义 TS新增了一个重要概念 接口 分为对象类型接口和函数类型接口 接口可以约束对象 函数 类的结构和类型 是一种代码协作必须遵守的契约 Interface 是一种描述对象或函数的东西 你可以把它理解为形状 一个
  • 使用github免费搭建个人博客后的写作及上传说明

    项目地址 我的博客github项目地址 个人博客网站 欢迎进入我的博客 本篇文章介绍如何在博客搭建好的基础上 使用它 使用它来写博客 更新博客页面 第一种方法 本地编辑 上传到github 首先 从我的github个人博客项目仓库克隆出该工
  • vscode中CommandNotFoundError: Your shell has not been properly configured to use ‘conda active的可能解决方法

    一 问题背景 如题 出现该问题后 我首先通过搜索尝试了conda init 用管理员身份运行powershell进行权限配置等方法无果 python之 vscode中激活conda虚拟环境报错或者打开虚拟环境失败 if using cond
  • 滑动时间窗口的思想和实现,环形数组,golang

    固定时间窗口 在开发限流组件的时候 我们需要统计一个时间区间内的请求数 比如以分钟为单位 所谓固定时间窗口 就是根据时间函数得到当前请求落在哪个分钟之内 我们在统计的时候只关注当前分钟之内的数量 即 0s 60s 因为流量并不是均匀的 所以
  • 微软RIA服务2009年7月预览版官方手册第2节(翻译:戴石麟)

    2 理解N层Silverlight应用项目 微软 NET RIA服务通过结合ASP NET和Silverlight平台来简化传统N层应用模式 应用逻辑写在中间层上 通过查询 更新 定制方法和服务操作来控制对数据的访问 NET RIA服务特性
  • Verilog入门学习笔记:Verilog基础语法梳理

    无论是学IC设计还是FPGA开发 Verilog都是最基本 最重要的必备技能 但任何一门编程语言的掌握都需要长期学习 并不是简简单单的随便读几本书 随便动动脑筋那么简单 Verilog是一门基于硬件的独特语言 由于它最终所实现的数字电路 具
  • netstat详解

    netstat是控制台命令 是一个监控TCP IP网络的非常有用的工具 它可以显示路由表 实际的网络连接以及每一个网络接口设备的状态信息 netstat可以用于显示与IP TCP UDP和ICMP协议相关的统计数据 一般用于检验本机各端口的
  • vb wor转存html,利用VB操作WORD的基本方法

    利用VB操作WORD的基本方法 通过查阅资料 自我实践 经实验通过 先引用word Application Dim MyWord As Word Application Dim MyWordBook As Word Document Set
  • Numpy:基础数据结构

    1 数组的基本属性 import numpy as np ar np array 1 2 3 4 5 6 7 print ar 输出数组 注意数组的格式 中括号 元素之间没有逗号 和列表区分 print ar ndim 输出数组维度的个数

随机推荐

  • Python @函数装饰器及用法(超级详细)转

    Python 内置的 3 种函数装饰器 分别是 staticmethod classmethod 和 property 其中 staticmethod classmethod 和 property 都是 Python 的内置函数 那么 我们
  • layui子弹框调用父弹框方法

    var thisFrame parent window document getElementById LAY layuiStampDuty1 getElementsByTagName iframe 0 id 获取父级弹框id值 var d
  • 【20220412】文献翻译4:交互中的手势和语言概述

    Gesture and speech in interaction An overview 1 简介 2 什么是共同语言 同声传译 手势 2 1 用手比划 2 2 用头做动作 3 语音和手势是交互的 3 1 交际环境中的手势 3 2 传递意
  • 双向链表

    双向就意味着对于每一个元素 都有两个方向的指向 因此从以下几个方面阐述双向链表 重要方法分析 全部代码 一 重要方法分析 这里的链表实现了我博客中的接口 ILinkedList 与结点 LinkedNode 具体的博客地址 http blo
  • 【Linux】VIM使用

    第一节 Vim常用操作 Vim没有菜单 只有命令 Vim的工作模式有三种 第一种 命令模式 vi vim 文件名 进入命令模式 不可以输入文字 只能识别命令 插入命令 a 在光标所在字符后插入 i 在光标所在字符前插入 o 在光标下插入新行
  • Vue基础精讲 —— Vue的组件之组件的定义、继承、自定义双向绑定、高级属性

    Vue组件基础定义 import Vue from vue const compoent props active type Boolean required true validator value return typeof value
  • UE4-蓝图基础:TimeLine

    一 概念 1 TimeLine 在一定时间内不断执行的一个蓝图节点 2 添加一个空白节点 函数讲解 Play 事件驱动 执行此事件时调用 Play from Start 从头开始执行事件 lt 事件在执行过程中未执行完毕 某一条件改变 事件
  • 回路电感详细介绍(环路电感)

    相比于硬件工程师 PCB工程师对环路电感更敏感 因为环路电感和走线强相关 不管是信号完整性还是电源完整性都涉及到这个概念 一旦电路结构确定 环路电感也随之确定 如果环路电感初期评估失误将会给后期改版带来巨大风险 更多资料请关注公众号 工程师
  • 操作系统 java模拟主存储器空间的分配和回收

    文章目录 实验原理 算法流程图 代码 结果 实验原理 模拟在可变分区管理方式下采用最先适应算法实现主存分配和回收 1 可变分区方式是按作业需要的主存空间大小来分割分区的 当要装入一个作业时 根据作业需要的主存量查看是否有足够的空闲空间 若有
  • 创建第一个Qt Widget项目

    创建第一个Qt Widget项目步骤 1 选择文件 Ctrl n 2 新建文件或项目 3 Qt Widget Application 4 输入项目名称FirstApplication 选择存储的位置 5 选择构建套件Desktop Qt Q
  • numpy一维数组永远为列向量

    import numpy as np a np array 1 3 4 5 print a shape a np transpose a print a shape print a a np ravel a print a shape pr
  • 静态分析简介

    一 程序静态分析简介 Program Static Analysis 程序静态分析简介 Program Static Analysis 是指在不运行代码的方式下 通过词法分析 语法分析 控制流 数据流分析等技术对程序代码进行扫描 验证代码是
  • 【mysql安装报错(已解决)】ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)

    1 说在开头 我的 mysql 版本是 8 0 27 的 安装的时候 感觉每一步都没有错 但是就是不行 到连接本地数据库时 发现一直连不上 搞了好久 一直报下面的错 ERROR 1045 28000 Access denied for us
  • 一文带你聊聊MYSQL的锁和MVCC

    如果你觉得内容对你有帮助的话 不如给个赞 鼓励一下更新 本文内容总结自极客时间 MySQL实战45讲 专栏 LBCC 单版本控制 锁 基于锁的并发控制 这种方案比较简单粗暴 就是一个事务去读取一条数据的时候 就上锁 不允许其他事务来操作 当
  • 【Python自动化】生成带装饰图形的渐变背景文字封面

    Python自动化专栏 利用文字生成固定比例且带有装饰图形的封面 文章目录 一 背景介绍 二 功能介绍 效果预览 功能清单 三 过程拆解 1 渐变背景层 2 装饰图形层 3 半透明遮罩层 4 文字层 四 完整代码 参考文档 一 背景介绍 在
  • echarts地图map下钻到镇街、KMZ文件转GeoJson、合成自定义区域

    echarts 地图map下钻到镇街 KMZ文件转GeoJson 合成自定义区域 我们可以通过 http datav aliyun com tools atlas 阿里旗下的高德地图提供的api 可以获取到中国各个省份 区级 县级的json
  • NAT技术的主要实现方式及其对网络应用程序的使用影响

    网络地址转换 NAT 是接入广域网 WLAN 的一种技术 能够将私有 保留 地址转化为合法的IP地址 它被广泛应用于各种类型Internet接入方式和各种类型的网络中 NAT的实现方式有三种 静态转换 动态转换和端口多路复用 静态转换设置起
  • Linux审计与日志安全加固

    审计和日志服务配置 auditctl 审计数据配置 日志文件最大参数 在储存策略 etc audit audit conf 中配置max log file
  • 高德地图精确查找与定位RegeocodeQuery与GeocodeQuery

    根据输入的字符串精确查找位置 用GeocodeQuery查找坐标 然后根据获取到的坐标 用RegeocodeQuery查询地址 例子中用了两个页面 一个是显示地址信息及定位的页面 另一个是搜索页面 点击搜索结果返回显示页面 显示信息并定位
  • iOS经典面试题总结--内存管理

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 我根据自己的情况做了一下总结 答案是我总结的 如有答的不好的地方 希望批评指正以及交流 谢谢 内存管理 1 什么是ARC ARC是automatic reference c