为什么发布返回(oneway void)但autorelease返回(id)?

时间:2011-12-06 13:50:35

标签: objective-c

如果我这样做 -

SomeObject* someObject = [[SomeObject alloc] init];
[[someObject release] release];

我认为我的程序不会崩溃,因为第二次过度释放没有任何作用。

尽管

[[someObject autorelease] autorelease];

会崩溃,因为该对象是通过向下传递而释放两次的。

这只是一个好奇的问题,我想我到目前为止从来没有遇到任何问题。

3 个答案:

答案 0 :(得分:7)

(有关oneway的解释,请参阅this answer。)

你的第一个例子甚至没有编译,因为void!= nil。但是如果你只是在一个保留计数为1的对象上调用release两次,它肯定会崩溃。

为什么release返回voidautorelease返回id:第一个说我不再需要这个对象,你可能会摆脱因此,如果它会返回某些东西而你会对它进行操作,那么你很可能会对一个死对象进行操作。相比之下,autorelease或多或少地说“很快我就不再需要这个对象了,但是在我完成当前方法之前让它保持不变。”

因此,当你看到它们相似时,他们会说我将不再需要这个对象,但它们的时间不同:release“你可以摆脱对象现在,而autorelease”你可以摆脱对象以后

答案 1 :(得分:4)

我认为这主要是为了易于使用而做的,因为当然可以没有(并将每个autorelease放在自己的行上):

每当你release一个物体时,你已经完成了它(或者至少你应该这样做)。没有必要返回对象,因为它可能已经被销毁了,并且在任何情况下,如果对象尚未被销毁(即其他人有对它的引用),则调用者不应该使用该对象。

另一方面,autorelease通常与init / alloc一起使用,只是标记该对象以供日后破坏。每当使用autorelease时,几乎可以确定之后是否正在使用该对象。无论您是直接返回它还是自己使用它(例如在[[[SomeClass alloc] init] autorelease]之后),都​​可以非常方便地返回对象,因为它为autorelease保存了明确的代码行。将autorelease直接放在同一行中也很有帮助:在return [someObject autorelease]上,您可以直接看到,这是一个自动释放的对象。如果您将其与init / alloc一起使用,则可以直接看到此对象不需要其他release

答案 2 :(得分:1)

我相信,你自己已经回答了你的问题。对自动释放的调用可能在对象生命的最初阶段,因此您可能需要通过以下语句保存一些代码行:

[anotherObject callMethodWithArg: [myObject autorelease]];

确实,这很有帮助。但是,您在代码的最后调用了一个使用您的对象的发行版。通过说立即释放,你说你不再需要这个对象了。所以重用它的实例是没有意义的。另一种选择是,释放调用实际上可以立即释放对象,因此返回无效指针不是一个好主意=)