如何正确覆盖 UITableViewController 子类的 init()?

How to properly override init() for UITableViewController subclass?

我的 UITableViewController 子类 MatchTableViewController 具有以下属性:

class MatchTableViewController: UITableViewController {
    // MARK: - Properties
    var matches = [Match]()
    var dataModel: DataModel
    var apiModel: APIModel

我想通过覆盖初始化器来初始化 dataModelapiModel

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    // Init the DataModel
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
    let managedContext = appDelegate.persistentContainer.viewContext
    guard let historyEntity = NSEntityDescription.entity(forEntityName: "History",
                                                         in: managedContext)
        else {
            fatalError("Failed to load the History entry")
    }
    self.dataModel = DataModel(historyEntity: historyEntity,
                               managedContext: managedContext)

    // Init the APImodel
    self.apiModel = APIModel()
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    // Error here
}


override init(style: UITableView.Style) {
    // Init the DataModel
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
    let managedContext = appDelegate.persistentContainer.viewContext
    guard let historyEntity = NSEntityDescription.entity(forEntityName: "History",
                                                         in: managedContext)
        else {
            fatalError("Failed to load the History entry")
    }
    self.dataModel = DataModel(historyEntity: historyEntity,
                               managedContext: managedContext)

    // Init the APImodel
    self.apiModel = APIModel()
    super.init(style: style)
    // Error here
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

Xcode 在两次 super.init 调用后立即给我错误 'super.init' isn't called on all paths before returning from initializer。我不确定我在这里遗漏了什么。

问题是,如果 guard 中的值没有被赋值,super.init(...) 就不会被调用,非可选变量也不会被赋值。但是你想在 else {...} 中抛出 fatalError 所以在这里调用 super.init(...) 没有任何意义。

所以先调用super.init(...)然后再做其他事情

override init(...) {
    super.init(...)
    ... // do other stuff
}

然后确保在调用 super.init(...) 之前分配所有非可选全局变量。如果不这样做(像你的情况),使这些变量可选

var variable: Type?
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

}

当覆盖需要的 init 方法时,初始化程序 'init(coder:)' 必须由 'UITableViewCell'

的子类提供
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}