恕我直言,哪种方式“正确”是一个偏好问题。我不反对主张不使用的响应者autorelease
,但我更喜欢使用,autorelease
除非有绝对令人信服的理由不使用。我将列出我的原因,您可以决定它们是否适合您的编程风格。
正如 Chuck 所指出的,有一个半都市传说,即使用自动释放池会产生某种开销。这与事实相去甚远,这来自于使用 Shark.app 花费了无数小时从代码中榨取最后一点性能。尝试对此进行优化是“过早优化”领域的深度。当且仅当 Shark.app 为您提供硬数据时,您甚至应该考虑查看它,这可能是一个问题。
正如其他人指出的那样,自动释放的对象是“稍后释放”的。这意味着它们会徘徊,占用内存,直到“稍后的点”滚动。对于“大多数”情况,这是在运行循环休眠直到下一个事件(计时器、用户单击某物等)之前的事件处理过程的底部。
但是,有时,您需要尽快摆脱这些临时对象,而不是稍后。例如,您需要处理一个巨大的、数兆字节的文件,或者数据库中的数万行。发生这种情况时,您需要将 a 放置NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
在精心选择的点上,然后[pool release];
在底部放置 a。这几乎总是发生在某种“循环批处理”中,因此它通常位于某些关键循环的开始和底部。同样,这应该基于证据,而不是基于预感。Instrument.app 的 ObjectAlloc 是您用来查找这些问题点的工具。
不过,我更喜欢 的主要原因是autorelease
编写无泄漏程序要容易得多。简而言之,如果您选择走的路线,您需要保证最终发送到,在任何情况下。虽然这看起来很简单,但实际上很难做到。以你的例子为例:release
release
release
obj
// array is an instance of NSMutableArray
MyClass *obj = [[MyClass alloc] init];
[array addObject:obj];
// Assume a few more lines of work....
[obj release];
现在想象一下,由于某种原因,某处某事巧妙地违反了您array
的可变假设,可能是由于使用某种方法来处理结果,并且包含已处理结果的返回数组被创建为NSArray
. 当您发送addObject:
到该 immutableNSArray
时,将引发异常,并且您将永远不会发送obj
它的release
消息。obj
或者可能在 when was alloc
d 和所需调用之间的某个地方出现了问题release
,例如您检查了某些条件并立即错误地因为它让您忘记了以后必须return()
进行该调用。release
你刚刚泄露了一个对象。并且可能签了几天,试图找出你在哪里以及为什么泄露它。根据经验,您将花费大量时间查看上面的代码,确信它不可能是泄漏的源头,因为您非常清楚地发送obj
了一个release
. 然后,几天后,当您对问题的原因有所启发时,您将体验到只能被描述为宗教顿悟的事情。
考虑以下autorelease
情况:
// array is an instance of NSMutableArray
MyClass *obj = [[[MyClass alloc] init] autorelease];
[array addObject:obj];
// Assume a few more lines of work....
现在,发生什么不再重要,因为几乎不可能obj
意外泄漏,即使在极其不寻常或特殊的极端情况下也是如此。