iPhone - dequeueReusableCellWithIdentifier usage iPhone - dequeueReusableCellWithIdentifier usage objective-c objective-c

iPhone - dequeueReusableCellWithIdentifier usage


The purpose of dequeueReusableCellWithIdentifier is to use less memory. If the screen can fit 4 or 5 table cells, then with reuse you only need to have 4 or 5 table cells allocated in memory even if the table has 1000 entries.

In the second way there is no reuse. There is no advantage in the second way over just using an array of table cells. If your table has 1000 entries then you will have 1000 cells allocated in memory. If you are going to do that you would put them in an array and just index the array with the row number and return the cell. For small tables with fixed cells that may be an reasonable solution, for dynamic or large tables it is not a good idea.


As for cell identifier- Instead of just using "cell" for the identifier, and instead of using a unique identifier like the OP, could you use a "type-identifier"? For example, if my table had 3 types of cells- one with a very complicated sub-layout, one with just Style1, and one with Style2, I should identify those three all separately and then just rebuild them if dequeue comes up nil.

For example:

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{    NSString* ident = @"";    if(indexPath.section == 0) ident= @"complicated";    if(indexPath.section == 1) ident= @"style1";    if(indexPath.section == 2) ident = @"style2";    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:ident];    if(cell == nil){       if(ident == @"complicated"){          cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:ident] autorelease];          // do excessive subview building       }       if(ident == @"style1"){          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyle1 reuseIdentifier:ident] autorelease];        }       if(ident == @"style2"){          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyle2 reuseIdentifier:ident] autorelease];        }    }    if(ident == @"complicated"){       // change the text/etc (unique values) of our many subviews    }    if(ident == @"style1"){      [[cell textLabel] setText:@"Whatever"];    }    if(ident == @"style2"){      [[cell textLabel] setText:@"Whateverelse"];    }    return cell; }

(This code probably won't run because I wrote it here, but hopefully you get the idea. )

I don't think Apple would have created the whole reusable cell idea with identifiers if they wanted all the identifiers to be "cell", don't you think?


The documentation that helped me understand why the idiomatic way (the one you described first) works best was UITableViewCell class reference section on the initWithStyle:reuseIdentifier: method.

The reuseIdentifier subsection reads:

You should use the same reuse identifier for all cells of the same form.

And the "Discussion" subsection reads:

The reuse identifier is associated with those cells (rows) of a table view that have the same general configuration, minus cell content.

These statements make it clear to me that the idiomatic way to use dequeueReusableCellWithIdentifier inside of your implementation of tableView:cellForRowAtIndexPath: for your UITableViewDataSource creates one cell object for each visible row regardless of the total number of rows available.