【问题标题】:Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value after I try to reloadData()致命错误:在我尝试 reloadData() 后隐式展开 Optional 值时意外发现 nil
【发布时间】:2019-05-21 17:31:16
【问题描述】:

我正在创建一个应用程序来扫描条形码并添加条形码值(以及名称和日期,但稍后会处理)。扫描条形码后,我调用了 add 方法,该方法应该将其添加到我的 tableview 中,但我在 reloadData() 处遇到错误。

import UIKit

class FirstViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!

    var data: [Ticket] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        data = createArray()
    }

    func createArray() -> [Ticket] {
        let video1 = Ticket(number: "123456789", name: "First Name - Last Name", date: "May 18th, 2019, 7 am")
        let video2 = Ticket(number: "123456789", name: "First Name - Last Name", date: "May 18th, 2019, 7 am")

        return [video1, video2]
    }
}

extension FirstViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let ticket = data[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "TicketCell") as! TicketCell
        cell.setTicket(ticket: ticket)

        return cell
    }

    func add (_ code: String)
    {
        let tic = Ticket(number: code, name: "First Name - LastName", date: "May 18th, 2019, 10 am")
        print(tic.number1)
        print(tic.name1)
        print(tic.date1)
        data.append(tic)

        self.tableView.reloadData() // Error Occurs Here
    }
}

这是我从另一个控制器调用 add 方法的地方。字符串“code”是条形码的值:

func found(code: String) {
    FirstViewController().add(code)

    viewDidLoad()
}

【问题讨论】:

  • 显示如何以及在何处调用此add 方法。
  • 您很可能正在创建另一个没有情节提要的FirstViewController 实例,因此未设置tableView 出口。
  • 是的,你的编辑证明了我的理论。
  • FirstViewController() 创建视图控制器的一个新实例,它不是故事板中的实例。因此插座未连接,代码崩溃。
  • 永远不要自己打电话给viewDidLoad

标签: swift


【解决方案1】:

每次使用FirstViewController() 添加条形码时,您都在创建FirstViewController 实例,您可以使用委托来更新原始实例。

首先使用您的add 方法创建一个协议

protocol BarcodeScanDelegate: class {
    func add(_ code: String)
}

扩展FirstViewController以继承BarcodeScanDelegate并移动add方法

extension FirstViewController: BarcodeScanDelegate {
    func add (_ code: String) {
        let tic = Ticket(number: code, name: "First Name - LastName", date: "May 18th, 2019, 10 am")
        self.data.append(tic)
        self.tableView.reloadData()
    }
}

在第二个(条形码扫描)视图控制器中创建一个变量来保持对上述委托的引用

class BarcodeScanViewController: UIViewController {

    weak var delegate: BarcodeScanDelegate?

    func addScannedBarcode() {
        self.delegate?.add("BARCODE_HERE")
    }

}

现在,当您启动第二个(条形码扫描)视图控制器时,将其变量 delegate 分配给 self

class FirstViewController: UIViewController {

    @IBOutlet var tableView: UITableView!
    ...

    @objc func launchBarcodeScanner() {
        let viewController = BarcodeViewController()
        // or use following if you are using storyboard
        // let viewController = self.storyboard!.instantiateViewController(withIdentifier: "BarcodeVC") as! BarcodeViewController

        viewController.delegate = self // <<<

        self.present(viewController, animated: true)
    }
}

【讨论】:

  • 摆脱了错误但不会添加我扫描的条形码的值
  • 终于搞清楚了!感谢您的帮助和它真正有帮助的示例项目!
【解决方案2】:

您在情节提要的 FirstViewController 类中有 tableView。

但在这种方法中,您不会将票附加到现有数组。您正在为 FirstViewController 创建新实例。表格视图位于情节提要中,您正在以编程方式创建此 FirstViewController 实例。所以 IBOutlet 将为零。所以它崩溃了。

func found(code: String) {
    FirstViewController().add(code)//new FirstViewController instance
    viewDidLoad()
}

不要从另一个视图控制器添加代码,而是使用自定义委托将代码传递给 FirstViewController 并重新加载 tableview。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多