您的位置:首页 > 其它

关于NSAutoReleasePool的理解

2015-04-22 10:06 253 查看
http://eleda.iteye.com/blog/1108700
http://www.cnblogs.com/PirateCaptain/articles/2506330.html
NSAutoreleasePool
和 @autoreleasepool blocks 区别

/**
 xcode4.3引入ARC,release这块就有些变化,当你使用ARC,就必须将NSAutoreleasePool的地方换成 @autoreleasepool
 关于NSAutoreleasePool的解释官方的最清楚
 Important If you use Automatic Reference Counting (ARC), you cannot use autorelease pools directly. Instead, you use @autoreleasepool blocks instead. For example, in place of:
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init;
 // Code benefitting from a local autorelease pool.
 [pool release];
 you would write:
 @autoreleasepool {
 // Code benefitting from a local autorelease pool.
 }
 @autoreleasepool blocks are more efficient than using an instance of NSAutoreleasePool directly; you can also use them even if you do not use ARC.
 **/

我们都知道当一个object的release方法被触发时, 这个对象就被销毁了,
再也不能对它有任何引用, 否则就会出现异常. 但如果在销毁它时触发的是autorelease方法, 那这个object就进入了对应的autorelease pool, 它的生命就被延长了(当pool drain时才真正被销毁).autorelease pool中存放的对象会在其自身干枯(drain)时被release. 还有一点需要注意的是,
通常在销毁pool的时候用的不是它的release方法, 而是drain! 原因是为了让程序同时兼容Reference Counting内存管理环境 与 Garbge Collection环境, 因为在Garbage Colloection环境中drain的作用是触发collect garbage动作.

一般来说在应用的main thread中, 已经存在了一个autorelease pool. 有两种情况需要开发者自己新建autorelease pool:

在main thread中, 在某个方法中出现大量的autoreleased objects, 为了避免memory footprint的增大, 可以手动创建一些autorelease pool用来drain objects.
创建新的thread, 并在其中访问了Cocoa, 需要在访问的前创建autorelease pool, 访问结束后drain.

最后一点, 在每个thread中都会维持一个stack, 其中放置着所有在这个thread中创建但未销毁的pool, 每当一个新的pool创建后, 它就位于stack的最顶端, 相应autoreleased object就会放入其中. 当pool drain的时候, 它就会从stack的顶端移除, 并且release掉其包含的objects

ios自动释放原理

当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。

1. ojc-c 是通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0,
就会被系统销毁.

2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个部分后面会详细说到.

3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.

NSAutoreleasePool详解:

1. NSAutoreleasePool实际上是个对象引用计数自动处理器。NSAutoreleasePool可以同时有多个,它的组织是个栈,总是存在一个栈顶pool,也就是当前pool,每创建一个pool,就往栈里压一个,改变当前pool为新建的pool,然后,每次给pool发送drain消息,就弹出栈顶的pool,改当前pool为栈里的下一个
pool。

2. 在程序的入口main函数就调用NSAutoreleasePool,这样保证程序中不调用NSAutoreleasePool,但在退出时自动释放。新开线程最好实现NSAutoreleasePool

3. NSAutoreleasePool的管理范围是在NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];与[pool release];之间的对象

4. NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

当执行[pool autorelease]的时候,系统会进行一次内存释放,把autorelease的对象释放掉,如果没有NSAutoreleasePool , 那这些内存不会释放

注意,对象并不是自动被加入到当前pool中,而是需要对对象发送autorelease消息,这样,对象就被加到当前pool的管理里了。当当前pool接受到drain消息时,它就简单的对它所管理的所有对象发送release消息。

例如

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSString* nsstring;

char* cstring = "Hello CString";

nsstring = [NSString stringWithUTF8String:cstring];

[pool release];

5. alloc的对象必须显示释放

例如:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSString* string = [[NSString alloc] init];

[string stringByAppendingString:@"Hello World!"];

[pool release];

[nsstring release];

6如果使用Automatic Reference Counting(ARC).不能直接使用autorelease pools,而是使用@autoreleasepool{},

@autoreleasepool{}比直接使用NSAutoreleasePool效率高。不使用ARC的时候也可以使用

7 在引用计数环境中,drain和release一样,但是在garbage-collected环境中,使用drain,触发GC(in a garbage-collected environment, triggers garbage collection if the
memory allocated since the last collection is greater than the current threshold)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: