致命错误:在我尝试reloadData()后隐式展开一个Optional值时意外地找到nil

时间:2019-05-21 17:31:16

标签: swift

我正在创建一个扫描条形码并添加条形码值(以及名称和日期,但稍后再处理)的应用。扫描条形码后,我调用了add方法,该方法应将其添加到我的表格视图中,但是我在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()
}

2 个答案:

答案 0 :(得分:0)

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

但是在这种方法中,您不会将票证添加到现有数组中。您正在为FirstViewController创建新实例。 tableview在情节提要中,您正在以编程方式创建此FirstViewController实例。因此,IBOutlet将为零。所以它崩溃了。

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

与其添加来自另一个视图控制器的代码,不如使用自定义委托将代码传递给FirstViewController并重新加载tableview。

答案 1 :(得分:-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)
    }
}