我理解你需要在iOS上小心使用autorelease
。我有一个方法,它返回一个由调用者所需的对象 alloc
,在这种情况下——就我所知——我需要在返回对象之前向被调用方发送 autorelease
。
这很好,但一旦控制返回到手机(即处理完我的按钮单击后),似乎自动释放池就被释放了。我怀疑这就是它应该的方式,但我想知道在这种情况下的最佳做法是什么。
我已经从调用者发送了一个 retain
消息,这样对象就不会被释放,并在 dealloc
中显式释放它。
这是最好的方法吗?
我理解你需要在iOS上小心使用autorelease
。我有一个方法,它返回一个由调用者所需的对象 alloc
,在这种情况下——就我所知——我需要在返回对象之前向被调用方发送 autorelease
。
这很好,但一旦控制返回到手机(即处理完我的按钮单击后),似乎自动释放池就被释放了。我怀疑这就是它应该的方式,但我想知道在这种情况下的最佳做法是什么。
我已经从调用者发送了一个 retain
消息,这样对象就不会被释放,并在 dealloc
中显式释放它。
这是最好的方法吗?
自动释放池(typically),通常会在每次运行循环(iteration)之后被释放(release)。大致上,每个Cocoa和Cocoa Touch应用程序的结构都是这样的:
Get the next message out of the queue
Create an autorelease pool
Dispatch the message (this is where your application does its work)
Drain the autorelease pool
你所描述的是预期行为。如果你想使一个对象在这之后继续存在,你需要显式地保留它。
使用autorelease
是一种表示:“对象,我不再需要你了,但我会把你传递给其他可能需要你的人,所以不要马上消失。” 因此,对象将保持足够的时间,以便您可以从方法中返回它或将其给另一个对象。当某些代码想要保留该对象时,必须通过retain
来声明所有权。
请参阅内存管理指南了解使用autorelease
的正确方式所需的所有信息。
以下是苹果内存管理文档中提供的示例:
– (id)findMatchingObject:(id)anObject
{
id match = nil;
while (match == nil) {
NSAutoreleasePool *subPool = [[NSAutoreleasePool alloc] init];
/* Do a search that creates a lot of temporary objects. */
match = [self expensiveSearchForObject:anObject];
if (match != nil) {
[match retain]; /* Keep match around. */
}
[subPool release];
}
return [match autorelease]; /* Let match go and return it. */
}
是的,这是最好的方法。自动释放只适用于您知道的代码交互。一旦您存储了一个对象,您应该知道持有引用的对象不会在您使用完对象之前死亡/超出范围,或者您需要保留对象。
只有自动释放的对象才能保证在方法结束后被释放。毕竟,调用您方法的方法可能已经创建了自己的池并在您方法之后立即释放它。
[[[object alloc] init] autorelease]
方法初始化的对象时,但在你使用它之前,该对象已经消失了? - boboboboautorelease
的行为是非常可预测的——对象会一直存在,直到当前的自动释放池被清空,而这只会在当前事件循环结束时发生(除非你故意提前清空)。举个例子,如果你将一个实例变量指向该对象但没有对其进行保留操作,然后在很久之后尝试访问它,那么在你有机会使用它之前,该对象已经消失了——但这是因为你在没有保留对象时违反了内存管理协议。 - Chuck