Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView dequeueReusableCellWithIdentifier Theory

When apple developed the UITableView for the first iPhone they had a problem in performance when scrolling through it. Then one clever engineer discovered that the cause of this was that allocation of objects comes with a price, so he came up with a way to reuse cells.

"Object allocation has a performance cost, especially if the allocation has to happen repeatedly over a short period—say, when the user scrolls a table view. If you reuse cells instead of allocating new ones, you greatly enhance table-view performance."

Source: iOS Reference Library

To reuse a cell you use:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

Now, what I am wondering is, what actually happens here? Does it look in the TableView if there is a cell with that identifier and just returns that one? Well yea duh, but if it sends a reference instead of allocating and I have a table view with let's say 4 cells with the same identifier all visible. How can it multiply itself into four instances without allocating?

I want to know this because I am building a calendar type component and all the cells have the same structure only the text within changes. So if I could somehow reuse my cells instead of allocating I think I might get a better performance.

My own theory is that it allocates the four cells (simply because it has too). When a cell disappears from the screen it will be put in the TableView reuse queue. When a new cell is needed it looks in the que if a cell with the same identifier is available, it invokes prepareForReuse method on that cell and it removes itself from the queue.

like image 824
Mark Avatar asked Aug 23 '10 22:08

Mark


People also ask

What is the use of Resueidentifier in a Uitableview?

The reuse identifier is associated with a UITableViewCell object that the table-view's delegate creates with the intent to reuse it as the basis (for performance reasons) for multiple rows of a table view. It is assigned to the cell object in initWithFrame:reuseIdentifier: and cannot be changed thereafter.

Why do we use dequeueReusableCellWithIdentifier?

dequeueReusableCellWithIdentifier . Instead of creating every single cell and then selectively displaying them, we only create a handful of cells, enough to fill the screen and a little more. As we scroll, we reuse the cells offscreen, leading to a much more memory efficient task.

How does Tableview dequeue work?

When a UITableViewCell scrolls off the screen, it gets put in a pool to be reused. The dequeueReusableCell(withIdentifier:) method grabs one out of that reuse pool. It is reusing a UITableViewCell with the given identifier if possible.

How does Dequereusablecell func work internally?

This method dequeues an existing cell if one is available or creates a new one using the class or nib file you previously registered. If no cell is available for reuse and you didn't register a class or nib file, this method returns nil .


2 Answers

dequeueReusableCellWithIdentifier: only returns a cell if it has been marked as ready for reuse. This is why in almost every cellForRowAtIndexPath: method you will see something like

   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  if (nil == cell) {     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault                                    reuseIdentifier:CellIdentifier]; }  // Do something to cell  return cell;  

In effect, enough rows will be allocated to fill the visible part of the tableview (plus one or two more). As cells scroll off screen, they are removed from the table and marked as ready for reuse. As the queue of "available cells" grows, your line that asks for a dequeued cell will start obtaining a cell to use, at which point you will not have to allocate anymore.

like image 195
Jerry Jones Avatar answered Oct 05 '22 23:10

Jerry Jones


The code for deqeueueReusableCellsWithIdentifier: will look something like this:

(Taken from one of my own projects where I do something similar with views/pages in a paged scroll view)

- (UIView*) dequeueReusablePage {     UIView* page = [reusablePages_ anyObject];     if (page != nil) {         [[page retain] autorelease];         [reusablePages_ removeObject: page];     }     return page; } 

So it keeps a simple NSMutableSet with reusable objects.

When cells scroll off the screen and are not longer visible, they are put in this set.

So you start with an empty set and the set will only grow if you actually have more data to show then is visible on the screen.

Used cell scrolls off the top of the screen, is put in the set, then taken for the cell that appears at the bottom of the screen.

like image 38
Stefan Arentz Avatar answered Oct 05 '22 23:10

Stefan Arentz