A safer alternative for dequeuing custom UITableViewCells

Andrés Cecilia Luque
3 min readJun 11, 2018

--

When dequeuing and customizing a basic UITableViewCell using the most recent API (introduced back in iOS 6), you would do something like this:

When the cell becomes more complex, it’s necessary to create a custom subclass of UITableViewCell. For that, UITableView got you covered: during the setup of the tableView, you just need to register the new class to dequeue:

When doing that, the compiler raises the error Value of optional type 'CustomCell?' not unwrapped.

The main reason for this is the total independance between the register and the dequeueReusableCell methods: dequeueReusableCell doesn’t know if you previously registered a cell, and can’t infer its type. Thus, it requires casting from UITableViewCell to your custom subclass.

The usual ways of getting around this issue are:

All of them are workarounds for avoiding a compiler error, assuming that the cast would never fail.

But… can it?

Yes, it can. If the registered class is not the same as the one used for casting, the cast won’t succeed. That will also happen if the reuseIdentifier doesn’t match between the register and dequeueReusableCell methods. And depending on the implementation we chose from the ones above, we will experience a crash or a silent error.

Now, let’s go with the alternative.

Remember the way we were dequeuing cells prior iOS 6? Using the old dequeueReusableCell method, and creating a new cell in case that method was failing. We weren’t registering the cell type anywhere.

Using this method has important advantages:

  • All the necesary code for dequeuing cells is in the same place: this is improving your local reasoning.
  • You don’t need to use any workaround: the compiler doesn’t throw any error, the code can’t crash and it can’t silently fail (well, technically it can, but only if you assign different cell identifiers. For solving this, keep reading).
  • Because all the code is together, you can set the cell identifier to a constant and reuse it, preventing one of the possible failure points that we identified before.
  • Because now the developer is the one in charge of initialising the cell (it is not done automatically anymore), the compiler makes sure that the cast and the newly created cell are of the same type. This prevents the other failure point we talked about: it is not possible to have different types (the compiler will raise an error).

--

--