0

Inside my cell for row at indexPath, I have been using the following code to do most of my work because that is what I have been taught. I was wondering, is it necessary to always use if let to do this work? Because I never find that I ever fall into the else statement.

When would I need to use if let or just let inside cellForRowAtIndexPath?

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCellWithIdentifier("myCustomCell") as? myCustomCell {

    } else {
        return myCustomCell()
    }
}
user905182
  • 13
  • 1
  • 6
  • [Found this related question](http://stackoverflow.com/questions/36024543/is-force-cast-really-bad-and-should-always-avoid-it). As you can see there are differing opinions how to handle this. It depends on your situation what the `nil` signifies and how to handle it. – Arthur Sep 27 '16 at 14:00
  • Thanks alot @Arthur – user905182 Sep 27 '16 at 15:12

1 Answers1

0

UITableView has two dequeue modes:

  1. dequeueReusableCell(withIdentifier:): The table view tries to dequeue a cell. If there are none, it will try to create one using the cell you registered with the reuseIdentifier. If you didn't register a cell, it will return nil giving you the chance to create one yourself.

This is where the else clause in your code would come into effect. Basically never, since presumably you did register a cell class. Most likely in the Storyboard (by setting the identifier in the inspector) but you can also do it in code.

  1. dequeueReusableCell(withIdentifier:for:), note the additional parameter. The table view tries to dequeue a cell: If there are none, it will try to create one using the cell class you registered using the reuseIdentifier. If you didn't register a cell, it will crash.

Solution

If you can guarantee that a) the cell is correctly registered and b) the type of the cell is set correctly, you would generally use the second option. This avoids the exact issue you're having:

let cell = tableView.dequeueReusableCellWithIdentifier("myCustomCell", forIndexPath: indexPath) as! myCustomCell

(However, it is still perfectly fine to use if let even in this case.)

Arthur
  • 351
  • 1
  • 12
  • Thanks. It was a typo and should be as? not as!. Would there be any case where the program was not able to use the dequeue'd cell because of some weird reason (eg, not enough?) such that the else clause gets executed occasionally? Or perhaps, is there an example where I would definitely want to use if let else to capture the else statement? – user905182 Sep 27 '16 at 12:22
  • The else clause would only hit if you somehow entered the wrong reuse identifier (e.g. made a typo) or the wrong cell class. Try it: Put a print in the else clause and change the identifier in Storyboard. In your code the else will get executed. In my example, it will crash. Things like this we call a "programmer" or "configuration" error. You misconfigured something. We want this to crash so we can eliminate the problem during testing so it never makes it to our users (others might disagree). But if we assume that everything is setup correctly, then no, the else/crash will never happen – Arthur Sep 27 '16 at 12:35
  • Thanks. So basically, if I use if let, I should never return myCustomCell() in the else clause. It should always be something like fatalError() inside the else clause then? It was just confusing that returning something in the else clause was the way that I was shown, I thought there was a use for it. – user905182 Sep 27 '16 at 13:10
  • There is no "always"/"never". Always depends on your situation. Let's say you deliberately leave the identifier empty in Storyboard. Now you *want* to implement the else and return a cell since dequeuing can be nil. This is a perfectly fine use case. However, if you do set an identifier and expect to get a valid cell out, what does it mean if you get nil? Did you make a typo? In that case you can do a `fatalError` to make it explicit. Or do you think nil is fine? In that case you can silently return a "fallback" cell in the else. I personally want a loud error in most (not all :) cases – Arthur Sep 27 '16 at 13:40
  • Much appreciated. – user905182 Sep 27 '16 at 14:05