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

Swift 将self分配给tableview数据源时出错,swift,xcode,macos,swift4,nstableview,Swift,Xcode,Macos,Swift4,Nstableview,这是Xcode输出的错误 在展开可选值时意外发现nil 我有一个viewcontroller,它有一个tableview和几个按钮;这些按钮允许我插入或删除数据。似乎当我点击Add(通过segue以工作表的形式显示一个新的viewcontroller)时,应用程序会崩溃,出现上述错误。单击“删除”不会产生此影响。因此,这与将新的viewcontroller视为猜测有关。除了打印输出(lldb)之外,控制台不会进一步研究错误 这是我的密码 override func viewDidLoad() {

这是Xcode输出的错误

在展开可选值时意外发现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绑定

为什么我会犯这个错误

更新

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

问题: 您的
AddAlarmViewController
ViewController
的子类,而不是
NSViewController

AddAlarmViewController
viewDidLoad
中,您调用
super.viewDidLoad()
,它基本上调用
ViewController
viewDidLoad

但是…在本例中,
ViewController
是一个新实例,作为
AddAlarmViewController
的超类,它的任何属性都未初始化。
不管是什么,这可能不是你想要的

解决方案:
我猜您的
alarmTableView
nil
。显示如何分配此变量。如果您使用的是IB插座,请检查插座是否仍然有效。请完整共享此viewcontroller的代码?@bigubosu 1。删除
viewwillbeen
逻辑,并将其移回
viewDidLoad
。那部分很好。实际上,您只需通过故事板设置
数据源
&
委托
。@bigubosu Wait。。。有一个补丁。让我check@bigubosu啊。。。真蠢!发布答案…天哪。。实际上,在我为github做准备的时候,它要求我重写printClassInfo(),我觉得这很奇怪,但显然超出了我的想象。@bigubosu-Hah,我想知道为什么频繁调用
viewDidLoad
。这很奇怪。好。。。不管怎样,现在你可以继续了。快乐编码
class AddAlarmViewController: ViewController {    
//... 

    override func viewDidLoad() {
        super.viewDidLoad()
        //...
    }
}
class AddAlarmViewController: NSViewController {
//... rest as it is
}