OC中的内存管理02

四、自动释放池 (autorelease)

1)基本原理:

1> 自动释放池是OC里面一种内存管理的自动回收机制,一般可以将临时变量添加到自动释放池中,统一回收释放。

2> 当自动释放池销毁的时候,在自动释放池中所有的对象都会调用一次release方法。

3> OC对象只要发送一条autorelease消息,会把对象方法放在最近的释放池中(栈顶的释放池)。

4> autorelease实际上是延迟了release方法的调用,每一次autorelease就会把对象放在当前的autorelease pool中,当pool被释放时,在pool中所有的对象调用该一次release。

2)自动释放池的创建:

1> ios 5.0后:

@autoreleasepool{

//..........

}

2> ios 5.0之前:

NSAutoreleasePool *pool=

[[NSAutoreleasePool alloc]init];

//...............

[pool release] ;或者 [pool drain];

3)autorelease的使用:

1> 以前:

Book *book = [[BooK alloc] init];

[Student setBooK:book];

[book release];

2> 现在:

Book *book =[[[Book alloc] init] autorelease];

[Student setBook:book];

//不在调用[book release];

3> 快速创建对象的静态方法:

+ (id) person{

  return [[[Person alloc] init]autorelease];

}

外部调用[Person person]时,根本不用考虑什么时候释放返回Person对象。

4)autoreleasepool的相关疑问:

疑问:

  在iPhone项目中,main()中有一个默认的Autorelease Pool,程序开始时创建,程序退出时销毁,按照对Autorelease的理解,岂不是Autorelease Pool里的所有对象在程序退出时才release,这样跟内存泄露有什么区别?

解答:

  对于每一个Runloop, 系统会隐式创建一个Autorelease pool,并且把创建好的pool放在栈顶,所有的pool会构成一个栈式结构。在每一个Runloop结束时,当前栈顶的pool会被销毁,这样这个pool里的每个对象会执行release操作。

5)autoreleasepool的使用注意:

1> 在ARC模式下不能使用[[AutoreleasePool alloc] init] ,而应当使用@autoreleasepool。

2> 不要把大量的循环操作放在NSAutoreleasePool之间,这样会造成内存的峰值上升。

3> 对于大内存尽量避免使用这种方法,对于这种延迟释放机制还是少用。

4> sdk中一般利用静态方法创建并返回的对象一本都已经autorelease的,不在需要release了。

6)@property的参数

1> 参数可有可无:

@property int age;

@property(nonatomic,retain) NSString * name;

2> 参数的分类:

读写属性:readwrite/readonly;

setter处理:assign/retain/copy;

原子性:atomic/nonatomic;

3> 默认参数是atomic

提供多线程保护,在多线程保护下,原子操作是有必要的,否则可能引起错误的结果。

加了atomic,setter/getter是一个原子操作,如果有多个线程同时调用setter的话,不会出现某个线程在执行setter的全部语句之前,另一个线程开始执行setter的情况,相当于函数头尾加了锁一样的。

4> 常用的参数noatomic

写上之后是说明禁止多线程,保护变量,提高性能。

atomic是OC使用的一种多线程保护机制,防止写入没有完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iphone这种小型设备上,如果没有使用多线程的通讯编程,那nonatomic是一个非常好的选择。另外不涉及锁操作,所以它执行相对快点。

5> @property其他参数

readwrite: 产生setter\getter readonly: 只产生简单的getter,没有setter。

assign: 默认类型,setter方法直接赋值,而不进行retain操作

retain: setter方法release旧值,再retain新值

copy: setter方法release旧值,再copy新值

 

posted on 2015-09-04 14:07  菜菜的菜菜  阅读(161)  评论(0编辑  收藏  举报

导航