将self分配给tableview数据源时出错

问题描述 投票:2回答:1

这是Xcode输出的错误

在打开Optional值时意外发现nil

我有一个viewcontroller,有一个tableview和几个按钮;按钮允许我插入或删除数据。似乎当我点击Add(通过segue作为工作表引出一个新的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.
}

上面viewDidLoad func嵌入的我的Viewcontroller列出了我需要的协议

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)")
}

}

如果我删除发生错误的行,应用程序运行正常。但是我想覆盖委托和数据源并使用这些函数来进一步自定义表。我也在使用Cocoa Bindings。

为什么我收到此错误?

更新

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

swift xcode macos swift4 nstableview
1个回答
2
投票

问题:

class AddAlarmViewController: ViewController {    
//... 

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

你的AddAlarmViewControllerViewController的子类,而不是NSViewController

AddAlarmViewControllerviewDidLoad,你打电话给super.viewDidLoad(),它基本上叫ViewControllerviewDidLoad。 但是......在这种情况下,ViewController是一个新的实例,作为AddAlarmViewController的超级类,并且没有任何属性被初始化。 不管它是什么,它可能不是你想要的。

解:

class AddAlarmViewController: NSViewController {
//... rest as it is
}
© www.soinside.com 2019 - 2024. All rights reserved.