iOS: Using the Wrong dequeueReusableCellWithIdentifier!

For dequeuing table view cells, I’ve been using the dequeueReusableCellWithIdentifier: method for a while now. I guess it just auto-completed for me one time in Objective-C and, since it was shorter than the other auto-completed method – dequeueReusableCellWithIdentifier:forIndexPath:, I just kept using it without thinking much about it.

This presented a problem for me in Swift with optionals:

    override func tableView(tableView: UITableView,
        cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        if let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier") {
             // Configure the cell...
            return cell
        }

        return UITableViewCell()
    }

As you can see, when you use dequeueReusableCellWithIdentifier:, it returns an optional. This means you have to unwrap it and handle the case where it doesn’t exist by returning an empty UITableViewCell(), which I’m pretty sure would just crash your app if it ever got to that point. But, that’s the only “clean” solution I could come up with.

However, yesterday @allonsykraken pointed out to me that all I had to do was look at the method signatures for the two dequeuing methods!

func dequeueReusableCellWithIdentifier(identifier: String) 
    -> UITableViewCell?

func dequeueReusableCellWithIdentifier(identifier: String,
    forIndexPath indexPath: NSIndexPath) 
    -> UITableViewCell

As you can see, dequeueReusableCellWithIdentifier:forIndexPath returns an actual UITableViewCell, not an optional one! If you read the comment in the source code, it explains this a bit more:

func dequeueReusableCellWithIdentifier(identifier: String) 
    -> UITableViewCell?
// Used by the delegate to acquire an already allocated cell, 
// in lieu of allocating a new one.
    
func dequeueReusableCellWithIdentifier(identifier: String,
    forIndexPath indexPath: NSIndexPath)
    -> UITableViewCell
// newer dequeue method guarantees a cell is 
// returned and resized properly, 
// assuming identifier is registered

So just by using the correct dequeueReusableCellWithIdentifier method, my optional issue is easily solved!

    override func tableView(tableView: UITableView,
        cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier",
            forIndexPath: indexPath)

        return cell
    }

This is a good reminder to read documentation when things don’t work as they should! Thanks again @allonsykraken for pointing this out!

Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.