title: tableView.cellForRow(at: indexPath) returns nil?
body: <p>I am trying to implement a tableView with CoreData. The table has four sorting ways. I had no problem implementing the first three but the forth was different as it was an entity that has a relationship.
  In the second View Controller where I can add items I added function that fetch existing items info and displays them it their relative cells.</p>
  
  <p>The app has 2 viewControllers, one is for the tableView and the other is for adding/editing items which is being viewed by the tableView.
  The two classes is next :</p>
  
  <pre><code>import UIKit
  import CoreData
  
  class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate{
  
      @IBOutlet weak var tableView: UITableView!
      @IBOutlet weak var segment: UISegmentedControl!
  
      var controller: NSFetchedResultsController&lt;Item&gt;!
  
      override func viewDidLoad() {
          super.viewDidLoad()
  
  
  
          tableView.delegate = self
          tableView.dataSource = self
  
          //self.tableView.register(ItemCell.self, forCellReuseIdentifier: "ItemCell")
  
          generateData()
          attemptFetchRequest()
      }
  
      func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -&gt; CGFloat {
          return 150
      }
  
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
  
          if let sections = controller.sections {
  
              let sectionInfo = sections[section]
              return sectionInfo.numberOfObjects
          }
  
          return 0
      }
  
      func numberOfSections(in tableView: UITableView) -&gt; Int {
  
          if let sections = controller.sections {
  
              return sections.count
          }
          return 0
      }
  
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
  
          let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as! ItemCell
  
          configureCell(cell: cell, indexPath: indexPath as NSIndexPath)
          return cell
  
      }
  
      func configureCell (cell: ItemCell, indexPath: NSIndexPath) {
          let item = controller.object(at: indexPath as IndexPath)
          cell.configCell(item: item)
      }
  
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  
          if let objs = controller.fetchedObjects , objs.count &gt; 0 {
              let item = objs[indexPath.row]
  
              performSegue(withIdentifier: "ItemVC", sender: item)
          }
      }
  
      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
          if segue.identifier == "ItemVC" {
              if let destination = segue.destination as? ItemVC {
                  if let item = sender as? Item {
                      destination.itemtoEdit = item
                  }
              }
          }
      }
  
      func attemptFetchRequest() {
  
          let fetchrequest: NSFetchRequest = Item.fetchRequest()
  
  
          let dateSort = NSSortDescriptor(key: "created", ascending: false)
          let priceSort = NSSortDescriptor(key: "price", ascending: true)
          let alphabetSort = NSSortDescriptor(key: "title", ascending: true)
          let typeSort = NSSortDescriptor(key: "toItemType.type", ascending: true)
  
          if segment.selectedSegmentIndex == 0 {
              fetchrequest.sortDescriptors = [dateSort]
          }else if segment.selectedSegmentIndex == 1 {
              fetchrequest.sortDescriptors = [priceSort]
          }else if segment.selectedSegmentIndex == 2 {
              fetchrequest.sortDescriptors = [alphabetSort]
          }else if segment.selectedSegmentIndex == 3{
              fetchrequest.sortDescriptors = [typeSort]
          }
  
  
          let controller = NSFetchedResultsController(fetchRequest: fetchrequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
          controller.delegate = self
          self.controller = controller
  
          do{
              try controller.performFetch()
          } catch {
              let error = error as NSError
              print("\(error)")
          }
      }
  
      func controllerWillChangeContent(_ controller: NSFetchedResultsController&lt;NSFetchRequestResult&gt;) {
          tableView.beginUpdates()
      }
  
      func controllerDidChangeContent(_ controller: NSFetchedResultsController&lt;NSFetchRequestResult&gt;) {
          tableView.endUpdates()
      }
  
      func controller(_ controller: NSFetchedResultsController&lt;NSFetchRequestResult&gt;, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
          switch (type) {
          case .insert:
              if let indexPath = newIndexPath{
                  tableView.insertRows(at: [indexPath], with: .fade)
              }
              break
          case .delete:
              if let indexPath = indexPath {
                  tableView.deleteRows(at: [indexPath], with: .fade)
              }
              break
          case .update:
              if let indexPath = indexPath {
                  &gt;&gt;let cell = tableView.cellForRow(at: indexPath) as! ItemCell
                  configureCell(cell: cell, indexPath: indexPath as NSIndexPath)
              }
              break
          case .move:
              if let indexPath = indexPath {
                  tableView.deleteRows(at: [indexPath], with: .fade)
              }
              if let indexPath = newIndexPath {
                  tableView.insertRows(at: [indexPath], with: .fade)
              }
              break
          }
      }
  
      @IBAction func segmentChanged(_ sender: AnyObject) {
          attemptFetchRequest()
          tableView.reloadData()
      }
  
      func generateData() {
  
          let item1 = Item(context: context)
          item1.title = "Car of the cars"
          item1.price = 100000
          item1.details = "Nothing much to say, it's a crapy car, don't buy it"
  
          let item2 = Item(context: context)
          item2.title = "Rocket"
          item2.price = 50000
          item2.details = "It's not fast as the actual rocket, but still faster than a bicycle"
  
          let item3 = Item(context: context)
          item3.title = "bal bla bla"
          item3.price = 50
          item3.details = "The price talks!"
  
          let item4 = Item(context: context)
          item4.title = "Old is Gold"
          item4.price = 60000000
          item4.details = "It's old, but also considered as great inheritance"
      }
  
  
  }
  </code></pre>
  
  <p>and the class for the second view controller :</p>
  
  <pre><code>import UIKit
  import CoreData
  
  class ItemVC: UIViewController, UIPickerViewDelegate,                              UIPickerViewDataSource, UIImagePickerControllerDelegate,   UINavigationControllerDelegate {
  
      @IBOutlet weak var storesPicker: UIPickerView!
      @IBOutlet weak var name : UITextField!
      @IBOutlet weak var price : UITextField!
      @IBOutlet weak var details : UITextField!
      @IBOutlet weak var image: UIImageView!
  
      var stores = [Store]()
      var types = [ItemType]()
  
      var itemtoEdit: Item?
  
      var imagePicker: UIImagePickerController!
  
      override func viewDidLoad() {
          super.viewDidLoad()
  
          if let topItem = self.navigationController?.navigationBar.topItem {
  
              topItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: nil, action: nil)
          }
  
          storesPicker.delegate = self
          storesPicker.dataSource = self
  
          imagePicker = UIImagePickerController()
          imagePicker.delegate = self
  
          generateData()
  
          fetchRequest()
  
          if itemtoEdit != nil {
              loadData()
          }
  
      }
  
      func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -&gt; Int {
  
          var returnValue = 0
  
          switch component {
          case 0:
              returnValue = stores.count
          case 1:
              returnValue = types.count
          default:
              break
          }
  
          return returnValue
      }
  
      func numberOfComponents(in pickerView: UIPickerView) -&gt; Int {
          return 2
      }
  
      func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -&gt; String? {
  
          var returnValue : String!
  
          switch component {
          case 0:
              returnValue = stores[row].name
          case 1:
              returnValue = types[row].type
          default:
              break
          }
  
          print(returnValue)
          return returnValue
      }
  
      func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
          //update
      }
  
      func fetchRequest (){
          let storefetch : NSFetchRequest&lt;Store&gt; = Store.fetchRequest()
          let typefetch : NSFetchRequest&lt;ItemType&gt; = ItemType.fetchRequest()
  
          do {
              self.stores = try context.fetch(storefetch)
              self.types = try context.fetch(typefetch)
              self.storesPicker.reloadAllComponents()
          } catch {
              //print("fetch error")
          }
      }
  
  
      @IBAction func saveItem(_ sender: AnyObject) {
  
          var item : Item!
  
          let pic = Image(context: context)
          pic.image = image.image
  
          if itemtoEdit == nil {
              item = Item(context: context)
          } else {
              item = itemtoEdit
          }
  
          item.toImage = pic
  
          if let title = name.text{
              item.title = title
          }
  
          if let price = price.text {
              item.price = (price as NSString).doubleValue
          }
  
          if let details = details.text {
              item.details = details
          }
  
          item.toStore = stores[storesPicker.selectedRow(inComponent: 0)]
  
          &gt;&gt;item.toItemType = types[storesPicker.selectedRow(inComponent: 1)]
  
  
  
          ad.saveContext()
  
          _ = navigationController?.popViewController(animated: true)
          //dismiss(animated: true, completion: nil)
      }
  
      func loadData() {
  
          if let item = itemtoEdit {
  
              name.text = item.title
              price.text = "\(item.price)"
              details.text = item.details
              image.image = item.toImage?.image as? UIImage
  
  
              if let store = item.toStore {
  
              var index = 0
  
              repeat{
  
  
                  if store.name == stores[index].name {
  
                      storesPicker.selectRow(index, inComponent: 0, animated: false)
                  }
  
                  index += 1
              } while(index &lt; stores.count)
          }
  
              if let type = item.toItemType {
  
                  var index = 0
  
                  repeat{
  
  
                      if type.type! == types[index].type! {
  
                          storesPicker.selectRow(index, inComponent: 1, animated: false)
                      }
  
                      index += 1
                  } while(index &lt; types.count)
              }
  
  
          }
      }
  
  
  
      @IBAction func deleteItem(_ sender: UIBarButtonItem) {
          if itemtoEdit != nil {
              context.delete(itemtoEdit!)
              ad.saveContext()
          }
          _ = navigationController?.popViewController(animated: true)
      }
  
      func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
  
          if let img = info[UIImagePickerControllerOriginalImage] as? UIImage {
              image.image = img
          }
          imagePicker.dismiss(animated: true, completion: nil)
      }
  
      @IBAction func setImg(_ sender: AnyObject) {
  
          present(imagePicker, animated: true, completion: nil)
  
      }
  
      func generateData(){
  
          let store1 = Store(context: context)
          store1.name = "Karfour"
          let store2 = Store(context: context)
          store2.name = "خير زمان"
          let store3 = Store(context: context)
          store3.name = "BestBuy"
          let store4 = Store(context: context)
          store4.name = "Virgin"
          let store5 = Store(context: context)
          store5.name = "Max"
  
          let type1 = ItemType(context: context)
          type1.type = "eletronics"
          let type2 = ItemType(context: context)
          type2.type = "food"
          let type3 = ItemType(context: context)
          type3.type = "wears"
          let type4 = ItemType(context: context)
          type4.type = "books"
          let type5 = ItemType(context: context)
          type5.type = "weapons"
  
          ad.saveContext()
  
      }
  
  }
  </code></pre>
  
  <p>I tested the error and found that it and it was returning nill from the function : </p>
  
  <pre><code>let cell = tableView.cellForRow(at: indexPath) as! ItemCell
  </code></pre>
  
  <p>I am pretty sure about the outlets and setting the custom class the proper way so I tested and noticed that when I remove a certain line the error no longer shows up. Another thing I've noticed is that when I run the app for the first time in the simulator when no data of the app is stored it works totally fine even with the line that caused the problem before but, after that when I re-run the app the problem shows then.
  <a href="https://i.stack.imgur.com/HCdMG.png" rel="nofollow"><img src="https://i.stack.imgur.com/HCdMG.png" alt="core data model"></a><a href="https://i.stack.imgur.com/rDYqb.png" rel="nofollow"><img src="https://i.stack.imgur.com/rDYqb.png" alt="core data model"></a><a href="https://i.stack.imgur.com/OkETP.png" rel="nofollow"><img src="https://i.stack.imgur.com/OkETP.png" alt="core data model"></a><a href="https://i.stack.imgur.com/4wMWB.png" rel="nofollow"><img src="https://i.stack.imgur.com/4wMWB.png" alt="core data model"></a><a href="https://i.stack.imgur.com/P3CVW.png" rel="nofollow"><img src="https://i.stack.imgur.com/P3CVW.png" alt="error"></a>
  I searched for the cause making the return value of the cellForRow to be will but I couldn't find anything helpful.
  I hope from you to help me.
  Thanks in advance.</p>
  
  <p><strong>SOLVED</strong>
  Unwrap "cell" using if let as follows :</p>
  
  <pre><code>case .update:
          if let indexPath = indexPath {
              if let cell = tableView.cellForRow(at: indexPath) as? ItemCell {
                  configureCell(cell: cell, indexPath: (indexPath as NSIndexPath))
              }
          }
          break
  </code></pre>