如果我这样做 -
SomeObject* someObject = [[SomeObject alloc] init];
[[someObject release] release];
我认为我的程序不会崩溃,因为第二次过度释放没有任何作用。
尽管
[[someObject autorelease] autorelease];
会崩溃,因为该对象是通过向下传递而释放两次的。
这只是一个好奇的问题,我想我到目前为止从来没有遇到任何问题。
答案 0 :(得分:7)
(有关oneway
的解释,请参阅this answer。)
你的第一个例子甚至没有编译,因为void
!= nil
。但是如果你只是在一个保留计数为1的对象上调用release
两次,它肯定会崩溃。
为什么release
返回void
而autorelease
返回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]];
确实,这很有帮助。但是,您在代码的最后调用了一个使用您的对象的发行版。通过说立即释放,你说你不再需要这个对象了。所以重用它的实例是没有意义的。另一种选择是,释放调用实际上可以立即释放对象,因此返回无效指针不是一个好主意=)