views:

732

answers:

3
UITableViewCell *cell = [tableView 
dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
 reuseIdentifier:CellIdentifier] autorelease];
 ...
 return cell;

Wouldn't this code autorelease the cell before anything can be done with it? The cell itself has no retain as far as I know and when the ell is returned the autorelease would likely kick in, wouldn't it?

It seems to work either way, I'd just like to fully understand why it does.

A: 

Hi, it's worth you getting to grips with iPhone memory management a little more.

Basically, an [alloc] and a [copy] both increase your retain count by one. So the following line:

cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
 reuseIdentifier:CellIdentifier] autorelease];

increments the retain count on your new cell object, from zero to one.

You could then manually decrease the retain count back to zero when you were done with it, by typing the following:

[cell release];

instead of the autorelease. This would reduce its retain count to zero, at which point the iPhone system will automatically dealloc the memory for this object. [Note that you never call [cell dealloc] directly - rather, dealloc automatically happens when the retain count goes back to zero.]

However, you don't easily know when that cell will no longer be required. So instead you use [autorelease].

Without going into the depths of how autorelease works, effectively it gathers all objects that are no longer referenced and releases them (and therefore deallocs them) at the start of the next run cycle.

As long as you have a reference to the cell object it will not be autoreleased. The moment you have no reference to it, it will be added to the autorelease pool and will be dealloc'd in due course.

Sorry it's a bit involved - does that help??!

h4xxr
Not right!! Autorelease means later the count it back down to zero... calling [cell release] yourself will cause a crash later.
Kendall Helmstetter Gelner
Ya I already know that too. I understand reference counting jsut was unsure of how UITableViewCell's work. I've had objects released before I could retain them in the calling code, though this could have been caused by gdb.
Brenden
Kendall you downvoted too hastily... my whole text says that while you *could* manually release it, you have instead (correctly) set it to autorelease. Obviously if you actually called [cell release] having also used [autorelease] it would crash! *sigh* wishing people would read before downvoting...
h4xxr
Brenden, your question states "The cell itself has no retain as far as I know" which is what I was correcting... the [ alloc] statement increases the retain count by one.
h4xxr
h4xxr, I know the cell has a retain, but it will be auto-released. My gray area is when that happens. I assumed after it returns the pool gets drained. I'm unfamiliar with when the auto pool is drained.
Brenden
aha ok cool, well as I and others have mentioned, it's at the start of the next run loop. :-) And remember, the cell will be autoreleased only when its retain count is zero, which will only happen when the parent (UITableView) itself is released.
h4xxr
+2  A: 

Autoreleases don't "kick in" until the NSAutoreleasePool is drained, which is not done when a method returns. Unless you create an NSAutoreleasePool manually, the pool is drained during the event loop. As long as you add the table cell to a UITableView (which retains it) before returning to the event loop, the cell will stick around.

John Calsbeek
+1  A: 

When you return a cell, you are following the standard convention that objects created by methods are autoreleased, and that if something cares about the objects it needs to retain them.

In this case, that "something" is the UITableView asking you for a cell. When this method returns the cell, then the code calling you retains it and keeps it around until the table view is released.

So why doesn't the autorelease cause it to free before it's returned? Because everything that happens in Objective-C is in what's called a "RunLoop", which means exactly that - it's a loop that is run again and again. After the table view finishes calling you it returns, then the thing telling the table view to update returns, and so on until the top runloop is reached - at which time the autoreleases are performed and the cells retain count drops by one. But again, that's OK because the UITableView has retained it.

Kendall Helmstetter Gelner