All writing

UITableView Cell Reuse

Essential iOS foundations

Notes on UITableView

UITableView appears throughout everyday iOS development. Understanding its internals makes it easier to use well and to diagnose scrolling performance problems.

Cell Reuse and Performance

How reuse works

For this discussion, assume the table view fills the entire screen.

The Contacts and Recents screens can scroll smoothly even when they represent hundreds or thousands of rows. That is possible because a table view does not create one cell for every item. It maintains only enough cells to cover the visible viewport, plus a small buffer.

When the table first appears, it creates the cells needed to fill the screen. The exact count depends on each row's height. As the user scrolls upward, the top cell moves offscreen while a new row needs to appear below the last visible cell.

Creating a brand-new cell for every row would defeat the purpose of reuse. Instead, UITableView retrieves an available cell from its reuse pool. A cell enters that pool after it has moved completely offscreen. If no compatible cell is available, the table creates one. Cells continuously move between the visible hierarchy and the reuse pool, so the total number of live cells stays close to the number required for a single screen.

This keeps memory and creation costs almost constant even when the data source contains thousands of items.

The implementation model

UIKit's implementation source is not distributed with Xcode, so I used Chameleon—an open-source UIKit implementation for macOS—as a learning reference. Although the project had already been inactive for several years, its structure was still useful for understanding the classic reuse model.

Creating a UITableView

When a UITableView is created, it also creates an empty reuse pool and maintains it internally. There are two common API patterns:

  • Ask for a reusable cell and create one manually when the pool returns nil.
  • Register a cell class or nib in advance, then dequeue a cell that the table view can instantiate when necessary.

Both approaches rely on the same principle: cells leaving the visible region become candidates for reuse instead of being discarded and recreated for every row.