Aaron You
Aaron You

Reputation: 117

When will dequeueReusableCell return nil?

I am new to the iOS programming scene and I recently came across some code examples online of implementations like:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    var cell = tableView.dequeueReusableCell(withIdentifier: customCellIdentifier, for: indexPath) as? CustomCell
    if (cell == nil) {
        cell = CustomCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: customCellIdentifier) asCustomCell
        }
    ...
    }

Where the author tried to handle the event where dequeueReusableCell return nil.

But from my limited personal experience with UITableView and custom cells, I have yet to encounter a time when dequeueReusableCell returned me nil.

From researching, I found the reason could be

"The dequeue… methods try to find a cell with the given reuse identifier that is currently offscreen. If they find one, they return that cell, otherwise they return nil."

from MrTJ's answer here

But that has never happened once to me. When I purposely give it a wrong identifier, a runtime error would occur but not once was nil returned. I wonder when exactly that would happen and if handling it is really necessary.

Upvotes: 3

Views: 1213

Answers (1)

Paulw11
Paulw11

Reputation: 114865

That code isn't correct. The older form of dequeueReusableCell without the indexPath parameter returns nil when there isn't an available cell in the reuse pool (i.e. when the table view first appears). In that case it is your responsibility to allocate a cell.

The newer form of dequeueResuableCell, shown in your question, will always return a cell as it allocates a cell if required.

The expression in your question can return nil if the conditional downcast fails (that is, the cell that was returned wasn't an instance of CustomCell).

I would argue that this represents a serious misconfiguration somewhere and should be found during development. For this reason a forced downcast is normally used; during development you get a crash, fix the problem and move on.

let cell = tableView.dequeueReusableCell(withIdentifier: customCellIdentifier, for: indexPath) as! CustomCell

The code in your question is some sort of Frankenstein mixture of the old and the new.

Upvotes: 6

Related Questions