OC的内存管理分为三种:
1,手动内存管理(MRC).
2,自动内存管理(ARC)
3,垃圾回收
IOS系统并不支持垃圾回收,现在主要使用ARC.但市场上还是有4.1版本前的软件使用MRC,所以MRC还是有学习的必要.
今天老师刚讲了MRC的一些基础知识,现在把老师讲解的一些问题和自己的问题写下来:
1,为什么需要内存管理?
现在的移动设备内存普遍不是很大,如果不使用内存管理,软件就会由很多的垃圾内存,最终导致内存泄露,软件崩溃.
2,内存管理的范围是什么?
所有父类为NSObject的对象.
3,内存管理的原理
每个对象都拥有一个或多个所有者,所有者就相当于计数器 retainCount,每当new或alloc创建一个对象是,计数器retainCount为1,调用retain方法,retainCount加1,调用release方法,retainCount减1,当retainCount为0时,该对象被销毁,所占用的内存被回收.每当对象被销毁时,系统会自动调用dealloc方法,像临终遗言一样,释放相关资源,一般会被重写.
手动内存管理最绕人的地方就是retainCount的计算.也就是retain,release的使用.如果程序结束,retainCount还大于0,就会有内存泄露.如果程序还未结束,retainCount就等于0了,就会出现野指针错误.
内存管理原则:
1,原则
只要还有人在使用某个对象,那么这个对象就不会被回收;
只要你想使用这个对象,那么就应该让这个对象的引用计数器+1;
当你不想使用这个对象 时,应该让对象的引用计数器-1;
2,谁创建,谁release
(1)如果你通过alloc,new,copy来创建了一个对象,那么你就必须调用release或者autorelease方法
(2)不是你创建的就不用你去负责
(3)谁retain,谁release ,只要你调用了retain,无论这个对象时如何生成的,你都要调用release
(4)总结
有始有终,有加就应该有减。曾经让某个对象计数器加1,就应该让其在最后-1.
因为现在有了@property(nonatomic,retain) 类型 变量名 这种直接声明实现setter和getter方法并且会自动调用retain方法,这样可以使调用的对象可以在程序的各个地方使用,因为自动调用了retain方法,所以每个类重写dealloc方法的时候需要把本类所拥有的实例对象release.
例:
@property (nonatomic,retain) Dog *dog;
就相当于 -(void)setDog:(Dog *)dog{
if(_dog != dog){
[_dog release];
_dog = [dog retain];
}
}
IOS5.0版本以后加入了自动释放池 @autoreleasepool
1,什么是自动释放池?
在IOS程序运行过程中,会生成无数的池子,这些池子都是以栈结构(先进后出)存在,当对象调用autorelease方法时,会将该对象放入自动释放池的顶部.
2,为什么会有autorelease?
因为在IOS中,内存管理遵守,谁创建,谁释放的原则.如果一个方法要返回一个新创建的对象,怎么办?方法内部不能release对象,否则刚创建立马就释放会返回一个空对象,因为遵循谁创建,谁释放的原则,调用者也不会release,这样就会造成内存泄露.而针对这种情况,Objective - c设计了autorelease.
3,autorelease的原理是什么?
autorelease实际上只是延迟了release的使用,系统把每一个调用autorelease的对象都放进自动释放池中,当自动释放池被释放时,给每一个对象都分配一个release.
4,autorelease的应用
一般会再创建对象的时候直接调用 例:Person *p =[ [Person new] autorelease]; 快速创建对象时也会经常使用:
MRC大致就是以上内容.
现在我们说下ARC.
IOS推出了ARC后,内存管理一下轻松起来.只用正常的编写代码,不用在写retain,release,retainCount.
1,ARC的工作原理:
ARC是编译器特性,是自动在你的代码的合适的位置插入retain,release,retainCount.而IOS的底层代码还是MRC.
2,ARC的判断标准:
ARC不再是引用计数器为标准,而是采用强弱指针为标准进行判断,当一个对象有强指针指(__strong)向时,就不会被销毁,没有强指针指向时,就会被销毁
__strong 代表强指针,__weak代表弱指针.
一个经典的问题
如何解决循环调用的内存管理?
这个问题从MRC和ARC两方面来回答:
如果是MRC 使用@property时参数一个使用retain,一个使用assgin.
如果是ARC 使用@property时参数一个使用strong,一个使用weak.