1

If I do this-

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

I presume my program wouldn't crash because the second over-release is acting on nothing.

Whereas

[[someObject autorelease] autorelease];

would crash because the object is released twice by being passed down the chain.

This is a matter of curiousity only, I guess I've never had a problem with it so far.

Ken
  • 30,811
  • 34
  • 116
  • 155
Sam
  • 3,659
  • 3
  • 36
  • 49

3 Answers3

7

(See this answer for an explanation what oneway does.)

Your first example doesn't even compile, as void != nil. But if you simply call release two times on an object that has a retain count of 1, it'll for sure crash.

As for why release returns void while autorelease returns id: The first says I don't need this object any more, you may get rid of it. Thus, if it would return something and you would operate on it you're likely to operate on a dead object. By contrast, autorelease more or less says "Soon I won't be needing the object any more but let it stick around until I'm done with the current method."

So as you see they are similar in that they say I won't be needing this object any more, but they differ in the time: release says "you can get rid of the object now", while autorelease says "you may get rid of the object later".

Community
  • 1
  • 1
DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • Good point about the compilation error- I presumed wrongly. Question answered, thanks. :) I suppose it does just come down to the fact you often return autoreleased objects but never a released one. – Sam Dec 06 '11 at 14:05
4

I suppose this is mainly done for ease of use, as one could of course do without (and put every autorelease on its own line):

Whenever you release an object, you're done with it (or at least you should be). There is no need to return the object as it may well have been destroyed already and in any case the caller should not work with the object if it is not yet destroyed (i.e. someone else has a reference to it).

On the other hand autorelease is often used in conjunction with init/alloc and just marks the object for later destruction. Whenever using autorelease one can almost be sure that the object is being used afterwards. Whether you directly return it or work with it on your own (e.g. after [[[SomeClass alloc] init] autorelease]) it is very handy to have the object returned as it saves an explicit line of code for autorelease. It is also helpful to have the autorelease directly in the same line: On return [someObject autorelease] you can directly see, that this is an autoreleased object. If you use it with init/alloc you can directly see that this object does not need another release.

Dennis Bliefernicht
  • 5,147
  • 1
  • 28
  • 24
1

I believe, you've answered your question yourself. Call to autorelease can be in the very beginning of object's life, so probably you'll need to save some code lines by the following statement:

[anotherObject callMethodWithArg: [myObject autorelease]];

Indeed, that's helpful. However, you call a release, in the very end of the code, that uses your object. By saying immediate release, you are saying you don't need this object here anymore. So there's no sense in reusing it's instance. Another option is, that a release call can actually deallocate the object immediately, so returning an invalid pointer will not be a good idea =)

Denis
  • 6,313
  • 1
  • 28
  • 27