最近在阅读了iOS内存管理相关的博客,总结归纳了一些内容,以及面试中常见的问题,写在这里供大家分享。
1.为什么要对堆区的内存空间进行管理,而基本数据类型不需要管理呢?
因为基本数据类型的数据会被放入栈中,它们依次紧密排列,遵循先进后出的原则,系统会自动进行管理。而对象类型会被存放在堆中,堆中的内存是不连续的,无法自动释放,所以需要我们进行管理。
2.内存管理的范围?
任何继承了NSObject的对象,对基本数据类型无效,主要对堆区的内存进行管理。
3.为什么要进行内存管理?
因为设备的内存空间是有限的,如果一直占用,而不回收空间,内存就会一直被占用,导致内存空间不足,严重会导致程序直接崩溃。因此,在开发过程中,需要进行内存管理,以保证高效快速的分配内存,并且在适当的时候释放和回收内存资源。
4.什么是内存溢出?
是指程序在申请内存时,没有足够的空间供其使用。例如:申请了一个integer,但存下了一个long才存的下的数。
5.内存管理的原理?
(1)对象的所有权及引用计数器
对象的所有权:任何对象都有一个或多个拥有者,只要一个对象至少还有一个拥有者,他就不会被释放
(2) 任何自己创建的对象都归自己所有,可以使用alloc和new开头或名字中包含copy的方法创建对象,使用return来获得一个对象的所有权。
(3) OC中都有专门8个字节的存储空间来存储引用计数器,用整数表示对象被引用的次数。
引用计数器是判断对象是否回收内存空间的依据。
(4) 给对象发送消息
return 计数器+1,方法返回对象本身
release 计数器-1,但不代表释放,autorelease 也可使引用计数器-1.
retaincount消息 用来获得当前引用计数器的值
引用计数器为0,系统向对象发送dealloc消息,(调用[super dealloc]方法,一定要写在后面)释放相关资源,对象被回收后将不能在被使用(僵尸对象),僵尸对象不可复活,否则会导致程序崩溃,导致野指针错误
6.iOS 内存管理的分类?
MRR (MRC) 手动内存管理(iOS 5之前):
(1)当每创建一个对象时,它的引用计数为1,当不再使用该对象是,需要向对象发送release或者autorelease消息释放对象。
(2)当你通过其他方法获得一个对象时,如果对象引用计数为1且被设置为autorelease,则不需要执行任何释放对象的操作;
(3)如果你打算取得对象所有权,就需要保留对象并在操作完成之后释放,且必须保证retain和release的次数对等。
ARC 自动内存管理(iOS 5后):
ARC 模式下不再需要进行retain或者release等操作,ARC会自动向对象发送retain和release消息,简化了内存管理步骤,节省大量的开发时间。
注意:
有时候工程的历史比较久,需要从MRC转换成ARC,具体操作如下
Build Phases -> Compile Sources 设置m文件的编译器参数 为 -fno-obje-arc