使用autorelease?

时间:2013-09-08 13:02:25

标签: objective-c

我不清楚如何使用autorelease;

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
RetainTracker* tracker = [RetainTracker new];
[tracker retain];
[tracker retain];
[tracker autorelease];
[pool release];

上面的代码中是否有内存泄漏?

我知道autorelease只是将tracker放入NSAutoreleasePool,而不修改tracker的引用计数。当我呼叫[pool release]时,对象会收到一条消息release,然后tracker的引用计数为2。因此编译器无法调用对象dealloc的{​​{1}}函数,因此存在内存泄漏。

所以我明白了:我们应该同时致电trackerretain,是不是?

2 个答案:

答案 0 :(得分:4)

如果您是Objective-c的新手,则应该使用自动引用计数。几乎每个人都应该。但为了理解:

对象具有引用计数的引用计数。当它下降到零时,该对象不被任何东西引用并被解除分配。 Objective-C中的每个方法都负责释放它保留的任何对象。问题是,如果工厂方法的工作是创建一个对象,它会通过不释放它保留的对象来破坏规则(在这个例子中,它被保留,因为它是创建的)。如果在返回对象之前对该对象调用release,则会将该地址返回给已经消失的对象。因此,有自动释放,它会暂时延迟释放,直到调用方法可以保留被调用方法创建的对象。

在上面的例子中,如果你摆脱了2个保留,并且只调用了自动释放,那么当自动释放池被释放并且(在释放之前)被释放时,该对象将被释放并释放,这意味着它会调用release on池中的所有对象,跟踪器都是其中之一,因为在跟踪器上调用autorelease将其添加到池中。

答案 1 :(得分:1)

new is equivalent to doing an "alloc" & "init",因此该行上跟踪器的保留计数为1.

然后再将保留计数增加2次,使总保留计数为3。

Autorelease设置在释放池时释放跟踪器(and the retain count is decremented as well)。但它已经保留了3次,所以它并没有真正发布。

是的,存在内存泄漏,保留计数大于0,并且在该方法之外没有引用“tracker”(即,除非您使用“tracker”在实例变量中。)

了解内存管理的基础知识非常好;但如果你想为自己节省大量的头痛,那就去做其他人在这里说的话,然后简单地启用ARC。

编辑:要完成您的问题,您应确保每次调用保留发布均衡。您还会执行“new”,这也会增加保留计数,因此您也需要“release”。