Swift:"致命错误:使用未实现的初始化程序' init()'上课......"

时间:2014-11-10 04:46:20

标签: macos cocoa swift

这是一个简单的类,我想用两个数组进行实例化,以在mac app上填充NSTableView:

class TableController: NSObject, NSTableViewDataSource, NSTableViewDelegate {

    var paintingNames:[String]
    var paintingKeys:[String]

    init(names:[String], keys:[String]) {
        paintingNames = names
        paintingKeys = keys
    //      breakpoint here shows both arrays have values
   }
...
}

当我在初始化代码时单步执行代码时,一切都可以解决。然后我收到了这个错误:

"fatal error: use of unimplemented initializer 'init()' for class..."

所以我可以通过添加数组选项(不是我想要的,因为它们是tableView的数据源)并添加覆盖init()调用来避免这个错误:

class TableController: NSObject, NSTableViewDataSource, NSTableViewDelegate {

var paintingNames:[String]?
var paintingKeys:[String]?

override init() { // this gets called after the first custom init function

    // a breakpoint here shows the arrays are now both nil
}

init(names:[String], keys:[String]) { //this gets called first
    paintingNames = names
    paintingKeys = keys
    //      breakpoint here shows both arrays have values
}
...
}

如果在重写init()调用中没有对数组进行nil检查,则数组为nil。即使添加了这一点逻辑:

override init() { // this gets called after the first custom init function
    if paintingNames != nil {
        paintingNames = [String]()
    }

    if paintingKeys != nil {
        paintingKeys = [String]()
    }
} 

他们仍然是零。

这里发生了什么?

1 个答案:

答案 0 :(得分:4)

将数组作为选项的原因是因为选项会自动分配nil

var paintingNames:[String]?
var paintingKeys:[String]?

完全相同
var paintingNames:[String]? = nil
var paintingKeys:[String]? = nil

此时您实际上可以删除init()声明,因为已经隐式为您创建了默认初始化程序。

您尚未添加任何代码来显示正在调用默认初始化程序的位置,我希望您不要调用两个init()函数...这是意外结果的处方。

如果您只想使用init(names:[String], keys:[String])初始化程序来实例化此类的对象,只需使您的默认初始化程序抛出异常,即

init() {
    fatalError("init() has not been implemented")
}

这可以防止您犯下使用init()创建对象的错误。另一种方法是将init()变为:

override convenience init() {
    self.init(names:nil, keys:nil)
}

如果您不知道,convenience初始化工具允许您在初始化程序中调用其他本地初始化程序。