Swift 3.1 TableViewCell 中的标签 - 意外发现 nil

Swift 3.1 Label in TableViewCell - unexpectedly found nil

我正在尝试在一个 UIViewController 中创建两个 tableView。但是,当我尝试为 UILabel 赋值时,出现错误:致命错误:在展开可选值

时意外发现 nil

我想知道为什么,我有几乎相同的 TableViewController 代码和一个 tableView,而且它没有问题。看起来这些 UI 标签在尝试为其赋值时未初始化。但是不明白怎么解决。

这里失败了:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell: UITableViewCell?
    if tableView == self.guestsTableView {
        let cell = tableView.dequeueReusableCell(withIdentifier: "guestCell", for: indexPath) as! GuestAtTableTableViewCell
        if let guestsTable = guestsTableFetchedResultsController?.object(at: indexPath) {
            print(guestsTable.guestName) // works fine, prints the value
            print(cell.guestNameLabel.text) //fails here with error fatal error: unexpectedly found nil while unwrapping an Optional value
            cell.guestNameLabel.text = guestsTable.guestName
            cell.openTimeLabel.text = String(describing: guestsTable.openTime)
            cell.cellDelegate = self
        }
    }
    else if tableView == self.ordersTableView {
        cell = tableView.dequeueReusableCell(withIdentifier: "orderCell", for: indexPath)
        //to be done
    }
    // Configure the cell...
    return cell!
}

这个class的完整代码:

import UIKit
import CoreData

class TableUIViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CellWithButtonDelegate {
    //The following two variables will not be nil because prepare for segue will set them
    var tableName: String?
    var table: TablesTable? = nil

    fileprivate var currentTableSession: TableSessionTable? {
        get {
            let tableSessionTable = TableSessionTable()
            return tableSessionTable.getCurrentTableSession(table: table!)
        }
    }
    fileprivate var guestsTableFetchedResultsController: NSFetchedResultsController<GuestsTable>?
    fileprivate var ordersTableFetchedResultsController: NSFetchedResultsController<OrdersTable>?

    @IBOutlet weak var tableNameLabel: UILabel!
    @IBOutlet weak var tableCapacityLabel: UILabel!
    @IBOutlet weak var tableCountOfGuestsLabel: UILabel!
    @IBOutlet weak var tableDescriptionTextView: UITextView!
    @IBAction func closeTableButtonPressed(_ sender: UIButton) {
    }
    @IBOutlet weak var guestsTableView: UITableView!
    @IBOutlet weak var ordersTableView: UITableView!

    @IBAction func addGuestButtonPressed(_ sender: UIButton) {
        let guestsTable = GuestsTable()
        let tablesTable = TablesTable()
        let table = Table(tableName: tableName!, tableCapacity: 0, locationX: nil, locationY: nil, tableImage: nil)
        try? guestsTable.addNewGuest(table: tablesTable.getOrCreateTable(table: table))
        updateUI()
    }
    @IBAction func addOrderButtonPressed(_ sender: UIButton) {
    }




    override func viewDidLoad() {
        guestsTableView.dataSource = self
        guestsTableView.delegate = self
        guestsTableView.register(GuestAtTableTableViewCell.self, forCellReuseIdentifier: "guestCell")

        ordersTableView.dataSource = self
        ordersTableView.delegate = self
        ordersTableView.register(UITableViewCell.self, forCellReuseIdentifier: "orderCell")
        updateUI()
    }

    func didPressButton(table: TablesTable) {
    }


    private func updateUI () {
        let tableView = guestsTableView
        let context = AppDelegate.viewContext
        let request : NSFetchRequest<GuestsTable> = GuestsTable.fetchRequest()
        request.predicate = NSPredicate(format: "table= %@", currentTableSession!)
        request.sortDescriptors = [NSSortDescriptor(key: "guestName", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))]
        guestsTableFetchedResultsController = NSFetchedResultsController<GuestsTable>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
        try? guestsTableFetchedResultsController?.performFetch()
        tableView?.reloadData()
    }

    private func updateUI1 () {
        let tableView = ordersTableView
        let context = AppDelegate.viewContext
        let request : NSFetchRequest<OrdersTable> = OrdersTable.fetchRequest()
        request.sortDescriptors = [NSSortDescriptor(key: "menuItem", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))]
        ordersTableFetchedResultsController = NSFetchedResultsController<OrdersTable>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
        try? ordersTableFetchedResultsController?.performFetch()
        tableView?.reloadData()
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell: UITableViewCell?
        if tableView == self.guestsTableView {
            let cell = tableView.dequeueReusableCell(withIdentifier: "guestCell", for: indexPath) as! GuestAtTableTableViewCell
            if let guestsTable = guestsTableFetchedResultsController?.object(at: indexPath) {
                print(guestsTable.guestName) // works fine, prints the value
                print(cell.guestNameLabel.text) //fails here with error fatal error: unexpectedly found nil while unwrapping an Optional value
                cell.guestNameLabel.text = guestsTable.guestName
                cell.openTimeLabel.text = String(describing: guestsTable.openTime)
                cell.cellDelegate = self
            }
        }
        else if tableView == self.ordersTableView {
            cell = tableView.dequeueReusableCell(withIdentifier: "orderCell", for: indexPath)
            //to be done
        }
        // Configure the cell...
        return cell!
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        if tableView == self.guestsTableView {
            return guestsTableFetchedResultsController?.sections?.count ?? 1
        }
        else if tableView == self.ordersTableView {
            return ordersTableFetchedResultsController?.sections?.count ?? 1
        }
        else {return 1}
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView == self.guestsTableView {
            if let sections = guestsTableFetchedResultsController?.sections, sections.count > 0 {
                return sections[section].numberOfObjects
            }
            else {
                return 0
            }
        }
        else if tableView == self.ordersTableView {
            if let sections = ordersTableFetchedResultsController?.sections, sections.count > 0 {
                return sections[section].numberOfObjects
            }
            else {
                return 0
            }
        }
        else {return 0}
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if tableView == self.guestsTableView {
            if let sections = guestsTableFetchedResultsController?.sections, sections.count > 0 {
                return sections[section].name
            }
            else {
                return nil
            }
        }
        else if tableView == self.ordersTableView {
            if let sections = ordersTableFetchedResultsController?.sections, sections.count > 0 {
                return sections[section].name
            }
            else {
                return nil
            }
        }
        else {return nil}

    }

    func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        if tableView == guestsTableView {
            return guestsTableFetchedResultsController?.sectionIndexTitles
        }
        else {
            return ordersTableFetchedResultsController?.sectionIndexTitles
        }
    }

    func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
        if tableView == guestsTableView {
            return guestsTableFetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
        }
        else if tableView == ordersTableView {
            return ordersTableFetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
        }
        else {return 0}
    }
}

以及 UITableViewCell 的完整代码 class:

import UIKit

class GuestAtTableTableViewCell: UITableViewCell {
    weak var cellDelegate: CellWithButtonDelegate?
    @IBOutlet weak var guestNameLabel: UILabel!
    @IBOutlet weak var openTimeLabel: UILabel!
    @IBAction func didPressButton(_ sender: UIButton) {
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

我猜你的 UITableViewCell 有一个 xib,注册 xib 而不是 class。 使用以下内容:

guestsTableView.register(UINib.init(nibName: "GuestAtTableTableViewCell", bundle: nil), forCellReuseIdentifier: "guestCell")

由于您已经在情节提要中创建了原型单元格,因此您应该 select 情节提要中的单元格并在那里设置其标识符。接下来从 guestCell 的代码中删除注册行。它应该工作