1

我不清楚如何使用autorelease

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

上述代码中是否存在内存泄漏?

我知道autorelease只是放入trackerNSAutoreleasePool而不修改tracker. 当我打电话[pool release]时,对象收到一条消息release,那么引用计数tracker2。所以编译器不能调用deallocobject 的函数tracker,所以存在内存泄漏。

所以我明白了:我们应该同时打电话retainrelease对吗?

4

2 回答 2

4

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

一个对象有一个引用计数,即有多少对象对其有引用。当它下降到零时,该对象不会被任何东西引用并被释放。Objective-C 中的每个方法都负责释放它保留的任何对象。问题是,如果工厂方法的工作是创建一个对象,那么它违反了规则,因为它不释放它保留的对象(在这个例子中,它被保留是因为它是被创建的)。如果该方法release在返回对象之前调用了该对象,则它将地址返回给已经消失的对象。所以,有autorelease,它会暂时延迟释放,直到调用方法可以保留被调用方法创建的对象。

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

于 2013-09-08T13:15:53.420 回答
1

new 相当于执行 "alloc" 和 "init",因此该行上跟踪器的保留计数为 1。

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

Autorelease 设置在释放池时释放跟踪器(并且保留计数也减少)。但它已经保留了 3 次,所以它并没有真正发布。

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

了解内存管理的基础知识非常好;但是,如果您想省去很多麻烦,只需按照这里其他人似乎在说的做,只需启用 ARC。

编辑:为了完成你的问题,你应该确保每次调用retain都与release保持平衡。你也做了一个“ new”,它也会增加保留计数,因此你也需要“ release”。

于 2013-09-08T13:09:47.863 回答