MRC&ARC
个人觉得内存管理这不是很容易学习理解,但是面试却总考.MRC现在几乎已经没有人用这个来编程.但是我们还要明白其中的原理,就像以后学的很多东西,都可以用三方轻松解决,但是还是从基础看起.所以今天在来复习一下ARC和MRC吧.记得初学这块时,有一种想要放弃的感觉.不过现在编码都是自动管理内存,想想这个,又坚持下来了.
一.iOS内存管理
ARC Automatic Reference Counting 自动引用计数
MRC Manual Reference Counting 手动引用计数
二.更改管理方式
三.内存管理问题
内存泄露:不需要的对象没有释放
野指针:正在使用的对象提前释放
僵尸对象:过度释放的对象。
iOS为了优化app性能,不会马上处理僵尸对象,如图所示可以开启僵尸模式。
引用计数:
1、每一个对象上都有一个引用计数器
2、当对象出生时引用计数器为1
3、当对象调用retain方法时引用计数器+1
4、当对象调用release方法时引用计数器-1
5、当一个对象引用计数为0时,这个对象立即被回收
dealloc 方法:
当对象的retainCount=0时自动调用。
dealloc里release成员变量对象。
dealloc必须调用父类方法,[super dealloc]必须放在最后。
dealloc由系统自动调用,不能手动调用。
dealloc的优化 成员变量对象直接置为nil;
内存管理原则:
谁申请,谁释放。
申请的方法:alloc new copy mutableCopy retain
释放的方法:release
Autorelease自动释放池
(一)基本用法
(1)会将对象放到一个自动释放池中
(2)当自动释放池被销毁时,会对池子里的所有对象做一次release
(3)会返回对象本身
(4)调用完autorelease方法后,对象的计数器不受影响(销毁时影响)
(二)好处
(1)不需要再关心对象释放的时间
(2)不需要再关心什么时候调用release
(三)使用注意
(1)占用内存较大的对象,不要随便使用autorelease,应该使用release来精确控制
(2)占用内存较小的对象使用autorelease,没有太大的影响
(四)错误写法
(1)连续调用多次autorelease,释放池销毁时执行两次release(-1吗?)
(2)Alloc之后调用了autorelease,之后又调用了release。
(五)自动释放池
(1)在ios程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的。
(2)当一个对象调用autorelease时,会将这个对象放到位于栈顶的释放池中
(六)自动释放池的创建方式
(1)ios 5.0以前的创建方式
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
`````````````````
[pool release];//[pool drain];用于mac
(2)Ios5.0以后
@autoreleasepool
{//开始代表创建自动释放池
·······
}//结束代表销毁自动释放池
(七)Autorelease注意
(1)系统自带的方法中,如果不包含alloc new copy等,则这些方法返回的对象都是autorelease的,如[NSDate date];
(2)开发中经常会写一些类方法来快速创建一个autorelease对象,创建对象时不要直接使用类名,而是使用self
ARC内存管理机制
(一)ARC的判断准则:
只要没有强指针指向对象,对象就会被释放。
(二)指针分类:
(1)强指针:默认的情况下,所有的指针都是强指针,关键字__strong
(2)弱指针:_ _weak关键字修饰的指针
声明一个弱指针如下:
__weak Person *p;
ARC中,只要弱指针指向的对象不在了,就直接把弱指针做清空操作。
__weak Person *p=[[Person alloc] init];//不合理,对象一创建出来就被释放掉,对象释放掉后,ARC把指针自动清零。
ARC中在property处不再使用retain,而是使用strong,在dealloc中不需要再[super dealloc]。
@property(nonatomic,strong)Dog *dog;// 意味着生成的成员变量_dog是一个强指针,相当于以前的retain。
如果换成是弱指针,则换成weak,不需要加__。
(三)ARC的特点总结:
(1)不允许调用release,retain,retainCount
(2)允许重写dealloc,但是不允许调用[super dealloc]
(3)@property的参数:
Strong:相当于原来的retain(适用于OC对象类型),成员变量是强指针
Weak:相当于原来的assign,(适用于oc对象类型),成员变量是弱指针
Assign:适用于非OC对象类型(基础类型)
MRC转ARC:
MRC与ARC混编:
ARCMRC
在的选项下下选择要不使用编译的文件,双击它,输入-fno-objc-arc即可
MRC工程中也可以使用ARC的类。
在的选项下下选择要使用编译的文件,双击它,输入即可
循环引用:A对象强指针引用了B对象,B对象强指针引用了A对象,彼此引用无法销毁。
解决方法:将其中的一条强指针改成用weak修饰的弱指针。