在Swift中对视图控制器进行子类化

时间:2017-09-11 09:03:58

标签: ios swift

我想继承UIViewController并覆盖init方法。我最终得到了:

class BaseViewController : UIViewController, BaseViewCreating, ModelBinding {

    var viewModel : Any!

    convenience init(viewModel: Any){
        self.init()
        self.createUserInterface()
        self.createConstraints()
        self.viewModel = viewModel
        self.bindWithModel(model: self.viewModel)
    }

    convenience init() {
        self.init()
        self.createUserInterface()
        self.createConstraints()
    }


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

    func createUserInterface() {

    }

    func createConstraints() {


    }

    func bindWithModel(model: Any) {


    }

    func update(){
        self.bindWithModel(model: self.viewModel)
    }
}

但是,当应用启动时,它会在方法self.init()的第convenience init()行引发错误 - EXC_BAD_ACCESS。 如何解决?

2 个答案:

答案 0 :(得分:2)

那是因为你在init recursively内打电话{/ 1}}

self.init

每个Convenient init都应该调用该类的指定初始化程序。 UIViewController有

convenience init() {
   self.init()
}

作为指定的初始化程序。因此,您应该在init()中调用其中任何一个,或者在ViewController中覆盖它们,然后调用public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) public init?(coder aDecoder: NSCoder) self.init(nibName

由于无法通过名称init()找到指定的初始化程序,因此它会以递归方式调用您的init,因此崩溃

修改

以防万一有人怀疑self.init不会导致循环,因为这是Convenience初始化程序可以调用指定初始化程序的方式之一。我在下面的评论中详细解释了为什么它会在这个特定情况下产生无限循环:)附上一个证据

enter image description here

这是我运行OP代码时的堆栈跟踪。清楚地显示无限递归调用

答案 1 :(得分:0)

如果有人遇到同样的问题,请在此处粘贴答案:

您应该将其添加到子类:

  init() {
        super.init(nibName:nil, bundle:nil)
        self.createUserInterface()
        self.createConstraints()
    }