17.3 自动释放池示例

看一下本章最后一个执行例子,以保证真正地理解对象的引用计数、保持和释放/自动释放的工作方式。检查代码清单17-6,该程序定义了一个名为Foo的虚类,它有一个实例变量以及一个继承来的方法。

代码清单17-6


import<Foundation/NSObject.h>

import<Foundation/NSAutoreleasePool.h>

@interface Foo:NSObject

{

int x;

}

@end

@implementation Foo

@end

int main(int argc, char*argv[])

{

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

Foo*myFoo=[[Foo alloc]init];

NSLog(@“myFoo retain count=%x”,[myFoo retainCount]);

[pool drain];

NSLog(@“after pool drain=%x”,[myFoo retainCount]);

pool=[[NSAutoreleasePool alloc]init];

[myFoo autorelease];

NSLog(@“after autorelease=%x”,[myFoo retainCount]);

[myFoo retain];

NSLog(@“after retain=%x”,[myFoo retainCount]);

[pool drain];

NSLog(@“after second pool drain=%x”,[myFoo retainCount]);

[myFoo release];

return 0;

}


代码清单17-6输出


myFoo retain count=1

after pool drain=1

after autorelease=1

after retain=2

after second pool drain=1


该程序分配了一个新的Foo对象,并且将它赋值给变量myFoo。前面已经看到过,它的初始保持计数为1。然而,这个对象并不是自动释放池的一部分,因此,释放池时,这个对象并没有失效。随后,定义了一个新池,并且向myFoo发送一条autorelease消息将其添加到池中。请注意,它的引用计数并没有改变,这是因为将对象添加到自动释放池时,并不影响它的引用数,仅仅是为了以后释放而进行了标记。

然后,向myFoo发送retain消息。这使得它的引用数变为2。随后再次释放池时,myFoo的引用数减为1,这是因为在前面向它发送了autorelease消息,所以,当池被释放时,会向myFoo发送release消息。

因为myFoo在释放池之前是保持的,所以它的引用数在减1后仍大于0。因此,myFoo对象在池释放后仍然有效。当然,现在你必须亲自释放它,在代码清单17-6中,就是这样来释放对象并避免内存泄漏的。

如果对此仍有些疑惑,请重新阅读关于自动释放池的解释。理解代码清单17-6之后,就彻底理解了自动释放池及其工作机理。