将自身分配给表视图数据源时出错

Error while assigning self to tableview datasource

这是错误Xcode输出

展开可选值时意外发现 nil

我有一个 viewcontroller,它有一个 table 视图和一些按钮;这些按钮允许我插入或删除数据。似乎当我单击“添加”(它通过 segue 作为 sheet 显示一个新的 viewcontroller)时,应用程序崩溃并出现上述错误。单击删除不会产生这种影响。所以它与有关新 viewcontroller 的猜测有关。除了打印出 (lldb)

之外,控制台不会进一步处理错误

这是我的代码

override func viewDidLoad() {
    super.viewDidLoad()
    alarmTableView.dataSource = self //error occurs here
    alarmTableView.delegate = self //if i remove the above line if will occur here too.
}

我的Viewcontroller上面的viewDidLoad函数是嵌入的列出了我需要的协议

class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {


    @IBOutlet weak var addAlarm: NSButton!
    @IBOutlet weak var resetDataButton: NSButton!
    @IBOutlet var alarmArrayController: NSArrayController!
    @IBOutlet weak var alarmTableView: NSTableView!
    @IBOutlet weak var deleteAll: NSButton!

    @objc let moc: NSManagedObjectContext

    required init?(coder: NSCoder) {
        self.moc = CoreDataHandler.getContext()
        super.init(coder: coder)
    }
    override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
        let destinationController = segue.destinationController as! AddAlarmViewController
        //pass data to next controller here

    }



    @IBAction func deleteAllAction(_ sender: Any) {

        if (alarmTableView.selectedRow >= 0) {
            if (CoreDataHandler.deleteAllObjectsInEntity(entityName: "Alarm")) {
                //remove from nsarray controller
                for object in alarmArrayController.arrangedObjects as! [Alarm] {
                    print(object)
                    alarmArrayController.removeObject(object)
                }

                alarmTableView.reloadData()
            }
        }
        else {
            printInfo(str: "There are no alarms to delete")
        }

    }


    /* Response to the remove alarm button  - It removes a selected alarm object from the table */
    @IBAction func resetDataAction(_ sender: Any) {
        if (alarmTableView.selectedRow >= 0) {
            let selectedAlarm = self.alarmArrayController.selectedObjects.first as! Alarm

            alarmArrayController.remove(atArrangedObjectIndex: alarmTableView.selectedRow)

            CoreDataHandler.deleteObjectInEntity(entityName: "Alarm", obj: selectedAlarm)
            alarmTableView.reloadData()
        }
        else {
            //will need a warning or play a sound.
            printInfo(str: "Please select an alarm")
        }

    }

    override func viewDidLoad() {
        super.viewDidLoad()
        printInfo(str: "viewdidload")
        print(alarmTableView)

        if (alarmTableView != nil) {
            printInfo(str: "AlarmTableView Is initialised")
            alarmTableView.dataSource = self
            alarmTableView.delegate = self
        }
        else {
            printInfo(str: "AlarmTableView is not initialised")
        }

    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    func printInfo(str: String) {
        print("ViewController: \(str)")
    }

    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
        return 100.0
    }
}

class AddAlarmViewController: ViewController {

@IBOutlet weak var closeButton: NSButton!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do view setup here.
    printClassInfo(str: "viewDidLoad")
    CoreDataHandler.saveTestData()


}

@IBAction func closeButtonAction(_ sender: Any) {
    self.dismissViewController(self)
}

func printClassInfo(str: String) {
    print("AddAlarmViewController \(str)")
}

}

如果我删除发生错误的行,应用 运行 没问题。但我想覆盖委托和数据源并使用函数进一步自定义 table。我也在使用 Cocoa 绑定。

为什么会出现此错误?

更新

我还没有解决它,但我在我的 viewDidLoad 函数中放置了几个打印语句。似乎首次加载应用程序时, table 视图已初始化。但是当我点击添加按钮后,table 视图由于某种奇怪的原因被设置为 nil,就好像另一个 table 视图已经被初始化一样。但是数据仍然可见

问题:

class AddAlarmViewController: ViewController {    
//... 

    override func viewDidLoad() {
        super.viewDidLoad()
        //...
    }
}

您的 AddAlarmViewControllerViewController 的子 class 而不是 NSViewController

AddAlarmViewControllerviewDidLoad 中你调用 super.viewDidLoad() 基本上调用 ViewControllerviewDidLoad.
但是... 在这种情况下 ViewController 是一个新实例,因为 AddAlarmViewController 的超级 class 和 none 的属性是已初始化。
不管是什么,它可能不是你想要的。

解决方案:

class AddAlarmViewController: NSViewController {
//... rest as it is
}