views:

97

answers:

2

I have a grouped UITableView in my UIViewController class and I'm finding that at times, the dequeued cell is not nil as expected.

The table has 3 sections to start with and and as soon as the 'viewDidLoad' is invoked, a server call is initiated to find out if there are more sections. Before the view is even rendered, the server's response arrives and we're told that we have 4 sections. To deal with this change, I do:

[self.tableview beginUpdates]

// Do the updating of the array that holds table data

[self.tableview endUpdates]
[self.tableview reloadData];

Next I get the call to 'numberOfSectionsInTableView', for which I return 4, followed by 'numberOfRowsInSection' and I'm returning the expected correct row count. Note this is the first time I'm getting either of these calls since the table reload happened so quickly and before the view was even rendered.

At this point, only the data from the 1st 3 sections are visible and scroll to view the last section. When you scroll to see the last section, one of the cells I'm expecting to be in the call to 'tableView:cellForRowAtIndexPath' is not nil as expected. The cell type is actually what was used for another section (I have one type of UITableViewCell for the 1st two sections and another for the last two sections that I'm creating and handing back in cellForRowAtIndexPath when cell is nil).

So how does UITableView figure out which cell to dequeue and how do I figure out why this cell for this particular section/row is not nil when it really should be?

+2  A: 

What are you using for your cell identifier? That's what a UITableView will use when determining what to dequeue. If you have different types of cells, you’ll need different reuse identifiers.

Jeff Kelley
This was exactly the problem. I thought that the entire table had to have the same cell identifier.
Justin Galzic
A: 

The idea of cell reuse boils down to minimizing view allocations and internal UITableViewCell setup in order to improve scrolling performance. Roughly speaking, whenever a cell goes off screen, a table view removes it from itself as a subview and adds it to a pool. The next time it needs to display a cell, you can dequeue an unused cell from the pool, configure it and return it to the table view. That's a clever implementation, but a table view cannot efficiently reuse cells without your hints, so called reuse identifiers.

The most common approach is to tie reuse identifiers to cell classes. If, say, you use cells of class A to display people from an address book and cells of class B to display organizations, you obviously cannot reuse cells B for people, and vice versa. In such a case you designate these two classes different reuse identifiers, which guarantees that when you need to provide cell A, the table will either dequeue a cell A or return nil if its pool of unused cells A is empty.

A natural extension to that is nil reuse identifiers. They tell a table view that it should not reuse them at all, releasing them when no longer on screen. Why may you need it? For unique cells or for the cells which you manage yourself, or for the cells which have an untypical life cycle, or are extremely expensive to draw. However, the fewer unreusable cells you have, the lower memory footprint.

Costique