Originally posted by swcrissman:
If the reference count is always valid, why couldnt you call release rather than autorelease every time? Autorelease just seems to be saying, hold on to this for a little while, then delete it if its reference count is 0, while release is saying, delete this if its reference count is 0.
More strictly speaking, autorelease just says "send this object a release later". The place where autorelease is most useful is when you have to return a value from a method call, and you have to manufacture the value, but you don't want the caller to have to release it. (In general, this is the convention --- return values should not be freed by the caller except in the alloc, copy, and new.)
Your example from your first message is indeed a good use of the autorelease.
Another place where autorelease is used is in a setXXX: method, where you are getting rid of the earlier value. There the question of release vs autorelease comes up. One reason to use autorelease is to make things safer. Consider the following methods in an object:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>- (NSString *)title {
<font color = green>return</font> myTitleInstanceVar;
}
- (<font color = green>void</font>)setTitle
NSString *)newTitle { <font color = brown>/* Vers A */</font>
[myTitleInstanceVar release];
myTitleInstanceVar = [newTitle copy];
}
- (<font color = green>void</font>)setTitle
NSString *)newTitle { <font color = brown>/* Vers B */</font>
<font color = green>if</font> (newTitle != myTitleInstanceVar) {
[myTitleInstanceVar release];
myTitleInstanceVar = [newTitle copy];
}
}
- (<font color = green>void</font>)setTitle
NSString *)newTitle { <font color = brown>/* Vers C */</font>
[myTitleInstanceVar autorelease];
myTitleInstanceVar = [newTitle copy];
}</font>[/code]
Vers A is scary for two reasons. Problem 1: if newTitle == myTitleInstanceVar, releasing first will clobber the value. Problem 2: If someone asked for the title with the "title" method, then immediately set a new title, the old title will be released out from under them:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
str = [obj title];
[obj setTitle:newTitle];
<font color = brown>/* str is now potentially invalid */</font></font>[/code]
Vers B solves the problem 1; but not 2. Vers C solves both, by lengthening the lifetime of the old title so anyone who asked for it will still have a valid, autoreleased reference.
Note that another way to solve problem 2 is to implement title this way:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>- (NSString *)title {
<font color = green>return</font> [[myTitleInstanceVar retain] autorelease];
}</font>[/code]
Which way you choose depends on which is more likely to be called: the title method, or setTitle:?
Note that for performance reasons, for very low-level set/get situations, you would not want to use autorelease. Setting the title of an NSWindow is one thing (happens relatively infrequently), but you wouldn't want thousands of autoreleases to happen when you insert or remove objects in an NSArray. So in some cases the unsafe route (vers B) might be taken, and this is indicated in documentation... Of course with an NSArray or NSDictionary this makes sense, as it's a simple container for values you provide.
Also, not sure when the 'end of the internal event loop' falls, exactly. I'm going to go read the article mentioned by honeydew (thanks!). Hopefully that will clear some things up...
By default the "end of the event loop" is when the AppKit handles and dispatches events. I think AppKit does something like:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>{
pool = [[NSAutoreleasePool alloc] init];
get and dispatch event
[pool release];
}</font>[/code]
Ali
[ 06-07-2001: Message edited by: ali ]