1

I have an application that has a UITableView with various custom UITableViewCells (and cell identifiers).

In my implemented tableView:cellForRowAtIndexPath: method I use the UITableView's dequeueReusableCellWithIdentifier: method and it gives me a UITableViewCell of the expected type when called during a user scrolling the table, but, if I try to retrieve a reusable cell in other parts of the code I'm getting nil as result, thus having to instantiate a new cell.

For example, the code I have that inserts new objects to be displayed looks like the following:

...
[myDataSource addObject:newObject];
...
[self.tv beginUpdates];
[self.tv insertRowsAtIndexPaths:paths withRowAnimation:rowAnimation];
[self.tv endUpdates];
...

That triggers an tableView:cellForRowAtIndexPath: and on that call the dequeueReusableCellWithIdentifier: returns nil although the cell that just left the screen was of the same type (same cell identifier) I'm inserting.

Shouldn't it be giving a reusable cell? In my case this may become problematic since my cells have a somewhat "heavy" init method due to their complexity.

Thanks in advance

Edit1: Just to clarify, I want to know why are no unused cell instances in the table cache to return since some cells (of the same type I'm inserting) just quit being visible?

ZeCodea
  • 1,071
  • 9
  • 26
  • this is normal behaviour, the cell you insert doesn't exist yet, so the controller must instanciate it. –  Dec 20 '11 at 15:42
  • but the cell I inserted is of the same type (and same identifier) of the cell that just quit being visible, that should now be reusable, shouldn't it? – ZeCodea Dec 20 '11 at 16:24

1 Answers1

4

Each cell in use requires it's own unique instance. As you are scrolling the table, iOS caches cells no longer in use and it is these unused instanced that are returned by tableView:dequeueReusableCellWithIdentifier:. In your case there are no unused instances in the cache to return.

As far as your init method goes, you shouldn't be doing anything time consuming in there. For example, if you are downloading remote content to display in the cell you should do that in the background and update the table/cell when it is complete.

XJones
  • 21,959
  • 10
  • 67
  • 82
  • yes I'm aware that I shouldn't be doing anything time consuming in cell's init. What I meant with "heavy" was 10-15 imageViews, among other controls, plus I can add multiple objects simultaneously, therefore having to create multiple cell instances (since they are not being dequeued), which might freeze the UI a bit. The question is "why are no unused instances in the cache to return since some cells just quit being visible?" – ZeCodea Dec 20 '11 at 16:20
  • 1
    the exact details of how UITableView manages its cache are opaque. Do you have a performance issue or are you concerned about one? It doesn't sound like your cell construction. should be an issue. creating/adding subviews is no problem. not sure what you mean by "create multiple cell instances." that's the whole purpose of a table. – XJones Dec 20 '11 at 16:35
  • If you are animating in a lot of cells at an `indexPath` where they all will be displayed you should be simply updating the dataSource and using `[tableView reloadData]`. – XJones Dec 20 '11 at 16:46
  • 'not sure what you mean by "create multiple cell instances."': for example if I add 5 objects simultaneously and they fit in the table view visible area, theis cells need to be dequeued/instantiated, if it took 100ms for each to be instantiated I would have a freeze of half a second on that operation. I'm not experiencing that issue right about now but I might – ZeCodea Dec 20 '11 at 16:49
  • the table will only instantiate visible cells. if you add a lot of data at once and the animation is slow then use reloadData instead. IMHO you're imagining a problem that doesn't exist. you won't have a problem instantiating cells. – XJones Dec 20 '11 at 16:56
  • thanks for your comments, maybe the problems won't come to be. Performance issues aside, shouldn't I get a reusable cell when calling dequeue after a cell insertion? or is it normal just to get reusable cells while scrolling? Edited the question to clarify it – ZeCodea Dec 20 '11 at 17:26
  • 1
    No problem. I suggest you not worry about when you get a dequeued vs new instance. Generally, yes, you should expect to get dequeue'd instances when scrolling. During insertion you may or may not get some, depends on the internal state of the tableView. Hard to predict exactly (and thus not worth worrying about). :) – XJones Dec 20 '11 at 17:34