oc 内存分配管理笔记

来源:互联网 发布:淘宝买恒压阀被警察抓 编辑:程序博客网 时间:2024/06/03 07:28

July 25,2014


内存问题体现在两个方面
1.内存溢出:一旦超出内存上限,程序就会 Crash
2.野指针异常:对象内存空间已经被系统回收,仍然使用指针操作这块内存.野指针异常是程序 crash 的主要原因.

内存管理的方式:
垃圾回收  (gc)
MRC (Manual Reference Count)  人工引用计数
ARC (Auto  Reference Count)   自动引用计数

gc: 程序员只需要开辟内存空间,不需要用代码显示地释放,系统来判断哪些空    间不再被使用,并回收这些内存空间,以便再次分配.整个回收的过程不需要写任何代码,由系统自动完成垃圾回收.

MRC:内存的开辟和释放都由程序代码进行控制.相对于垃圾回收来说,对内存的控制更加灵活,可以在自己需要释放的时候及时释放,对程序员的要求较高,程序员要熟悉内存管理的机制.

ARC:iOS 5.0的编译器特性,它允许用户只开辟空间,不用去释放空间.它不是垃圾回收!它的本质还是 MRC, 只是编译器帮程序员默认加了释放的代码.

iOS 支持两种内存管理方式: ARC 和 MRC
MRC 的内存管理机制是:引用计数
ARC 是基于 MRC


引用计数:
OC 采用引用计数机制管理内存,当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递增.当引用计数到零时,该对象就释放占用的资源.

影响引用计数的方法:
1.+alloc :  开辟内存空间,让被开辟的内存空间的引用计数变为1. 这是由0到 1得过程.
2.-retain:  引用计数加1,如果内存空间之前引用计数为1,retain 之后变为2,如果引用计数是5,retain 之后变为6.(相等于自增)
3.-copy:  把某一内存区域的内容拷贝一份,拷贝到新的内存空间里去,被拷贝区域的引用计数不变,新的内存区域的引用计数为1.(原有的不变,新的加1) (浅复制引用计数加1,深复制不变)    浅 copy 相等于  retain 一下
4.-release: 引用计数减1, 如果内存空间之前引用计数为4,release 之后变为3,如果之前引用计数为1,release 之后为0,内存被系统回收.(相等于自减,不是立即减1)

最后一次 release 后,即变为0之后,不能在使用指针和对象的任何东西,使用 的是野指针!也不能进行打印,这是一个错误的写法了!

5.-autorelease: 未来的某一时刻引用计数减1.如果内存之前引用计数为4,     autorelease之后仍然是4,未来某个时刻会变为3.

dealloc:
- dealloc 是继承自父类的方法,当对象引用计数为0的时候,由对象自动调用.
我们可以在dealloc 中打印一句话,验证对象引用计数是否降为0.
- (void)dealloc
{

     NSLog(@“%@被销毁了”,self);
     [super dealloc];//一定写在下面,先销毁自己变量的,最后销毁父类变量
}

autoreleasepool 的使用:
通过autoreleasepool 控制 autorelease 对象的释放.
向一个对象发送 autorelease 消息,这个对象何时释放,取决于autoreleasepool 

先写的先进来,但是后释放

写法:
NSAutoreleasePool *pool = [ [NSAutoreleasePool alloc]  init];
Person *p =[ [Person alloc]  init];//retainCount为1
[p retain];//retainCount 为2
[p autorelease];//retainCount 为2  未来的某个时刻释放
[pool release];
NSLog(@“%d”,[p retainCount]);//打印结果为1

在 iOS5之后,不在推荐使用 NSAutoreleasePool 类, 使用@ autoreleasepool{}替代.

写法为:
autoreleasepool
{
      
     [p  autorelease];
     [p  autorelease];

}


出了大括号,自动释放池向各个对象发送 release 消息.



内存管理的原则:
1.引用计数的增加和减少相等,当引用计数降为0之后,不应该再使用这块内存空间.
2.凡是使用了(只要你看到了)alloc retain 或 copy 这三个关键字,那么他们肯定是让内存增加了,就需要使用 release 或 autorelease 让内存的引用计数减少.这一段代码内,增加和减少的次数要相等.

// release  autorelease 释放成0的时候,自动调用dealloc


0 0
原创粉丝点击