In each case, you are dequeueing two cells for each row. In cases 1 and 2, you call the ("Cell", forIndexPath: indexPath)
version first. In this case the table view ends up with two cells for each row, one completely overlapping and obscuring the other. You can see this in the view inspector since you can amend the angle of view to see behind:
(I amended the cellForRowAtIndexPath
code like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("plainCell", forIndexPath: indexPath)
cell.textLabel!.text = "First cell for row (indexPath.row)"
cell = tableView.dequeueReusableCellWithIdentifier("plainCell", forIndexPath: indexPath)
cell.textLabel!.text = "Second cell for row (indexPath.row)"
print("Cell being returned is (cell)")
return cell
}
to given different text labels to each cell.) In cases 3 and 4, where you call the ("Cell")
version first, the table view has only one cell for each row.
Why the different behaviour? If you create a custom subclass of UITableViewCell
and use that in your storyboard, you can then override various methods and add print()
statements to see what's happening. In particular, awakeFromNib
, didMoveToSuperView
, and deinit
. What transpires is that in cases 1 and 2, the first cell is created (awakeFromNib) and immediately added (didMoveToSuperView) to a superview, presumably the table view or one of its subviews. In cases 3 and 4, the first cell is created but is not added to a superview. Instead some time later, the cell is deallocated (deinit).
(Note that if the second cell is dequeued using the ("Cell", forIndexPath: indexPath)
version, it too is added immediately to a superview. However, if the second cell is dequeued using the ("Cell")
version, it is only added to a superview after the cellForRowAtIndexPath
method has returned.)
So the key difference is that the ("Cell", forIndexPath: indexPath)
version results in the cell being added immediately to the table view, before even the cellForRowAtIndexPath
has completed. This is hinted at in the question/answer to which you refer, since it indicates that the dequeued cell will be correctly sized.
Once added to the superview, the first cell cannot be deallocated since there is still a strong reference to it from its superview. If the cells are dequeued with the ("Cell")
version, they are not added to the superview, there is consequently no strong reference to them once the cell
variable is reassigned, and they are consequently deallocated.
Hope all that makes sense.