I have seen people writing this code inside a table view delegate
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! SuitCell? else {
fatalError()
}
...
}
now consider this other code
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! SuitCell
...
}
Won't both codes crash at the same lines if the cell is not dequeued?
Is there any difference? I am not seeing it.
dequeueReusableCell(withIdentifier:)
can return nil
in the case where there are no cells in the re-use pool (i.e. When the tableview is first shown). When it returns nil
it is your responsibility to instantiate a cell of the appropriate type.
Therefore, this block of code:
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! SuitCell? else {
fatalError()
}
says "If you get a cell from the re-use pool and it isn't an instance of SuitCell
, crash, but nil
is OK" (Note the cast to an optional)
While this block of code:
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! SuitCell
Says "Crash if you don't get an instance of SuitCell
, or youn get nil
", so this will crash when the tableview is first shown.
dequeueReusableCell(withIdentifier:)
isn't really used any more. You would use the newer (but still been around since iOS 6) dequeueReusableCell(withIdentifier:,for:)
variant as it always returns a cell and you can expect it to be the right class (or you will quickly find your problem during development):
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! SuitCell