The hidden workings of UITableView

Image for post
Image for post

UITableViewCell has some interesting workings underneath the hood, giving a fantastic opportunity to think about how they work and some of the internal workings behind some of the basic iOS features.rerequisites:

  • Some basic understanding of Xcode, Swift and creating mobile Apps.

Terminology

UITableViewController: A view controller that specializes in managing a table view

UITableView: A view that presents data using rows arranging in a single column

UITableViewDataSource: The methods adopted by the object you use to manage data and provide cells for a table view

UITableViewCell: A visual representatation of a single row in a table view

The problem

If you naively created a tableview and did not reuse cells, you would waste memory and potentially crash your all — not great for your users!

When you implement the tableview with the traditional dequeueReusableCell(withIdentifier:for:) you can encounter further problems because the cells are reused.

These are covered (and problems solved) in the practical examples section below. However we first run through the theory

The theory

If you have a tableview with 100,000 rows they would all need to be stored in memory (at the same time). In the practical example, I found this took nearly 1GB of memory. However, it does not end there since a table may have more rows, and you would need to make sure that your App is not closed due to using too much memory.

As a solution you use a queue of cells. When you scroll through a table

Image for post
Image for post

When the cell is scrolled outside the visible area of the tableview, it is placed within the queue. When cells are taken from the queue it is sent to the cellForRowAt: method and the appropriate data is (re)entered into the cell.

Some we might be reentering data into a used cell Apple recommend that we reset attibutes of the cell that are not related content through prepareForReuse and tableView(_:cellForRowAt:) should reset all of the content when reusing a cell.

Practical examples

The git link implements the following code: https://github.com/stevencurtis/HiddenWorkingsUITableview

The poor implementation

The poorest implementation of a tableview does not reuse cells at all:

and, spectacularly, the code uses 1GB of memory.

Image for post
Image for post

This is obviously untenable as the the App may be closed due to the large memory footprint of this implementation.

A reuse implementation

This brings the memory usage down greatly.

Image for post
Image for post

The problem

When the images are loaded into reusable cells they can be not only displayed as the wrong size (in an implementation where we download images from an API):

Image for post
Image for post

But they can actually display the wrong image as it is the reused image!

To implement this we need to implement a custom cell using a NIB which requires a slightly different registration:

let cellNib = UINib(nibName: “ReusableTableViewCell”, bundle: nil)

tableView.register(cellNib, forCellReuseIdentifier: “ReusableTableViewCell”)

we can then download the image from within the cell and, most importantly use prepareForReuse(). It can be argued that prepareForReuse should only reset the attributes of the cell that are not content related, but the following code is only given for purposed of this post.

Here is that link to the Git repo:

Want to get in contact? Have a question? Hit me up on Twitter:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store