使用必需的编码器Init初始化子类化的UIViewController-怎么办?

时间:2018-11-06 02:03:37

标签: ios swift

这可能是迄今为止最愚蠢的问题-但是我在使用自定义的必需编码器初始化程序(特别是使用QRCoder pod)初始化子类视图控制器时遇到了问题;为了不公开我不拥有的代码,我将在我的情况下使用示例类)。

这是要领。

class A: UIViewController {

    public var name = String()

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        name = "This is a test"
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
}

那么我们有...

class B: A {


    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        name = "What what"
    }
}

例如,如果我尝试生成B的新视图控制器,请点击C ...上的按钮。

class C: UIViewController  {

    let button = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()

        button(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)}

    } 

    @objc func buttonTapped(_ sender: Any) {
        let viewOfB = B()
        present(viewOfB, animated: true)
    }
}

它没有编译=因为我对let viewOfB = B()的调用缺少了coder参数。

问题是,如果我添加一个coder参数,那我应该放什么呢?我试图用一个空的(?)NSCoder填充它,就像这样

let emptyCoder = NSCoder()
let viewOfB = B(coder: emptyCoder)

但是在运行和点击按钮时,出现以下错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -decodeObjectForKey: cannot be sent to an abstract object of class NSCoder: Create a concrete instance!'

我曾尝试向A添加便捷初始化程序(出于某种原因,我必须在其中运行self.init而不是super.init),但是这样做会使我得到EXC_BAD_ACCESS_ERROR。 / p>

我到底需要为init:(coder)实例提供什么才能使...正常运行?

1 个答案:

答案 0 :(得分:1)

  

我到底需要为init:(coder)实例提供什么才能使...正常运行?

什么都没有。不再考虑init(coder:)

这是实际的问题。当您说B()时,您正在呼叫init()。但是没有init(),因为它来自哪里?您没有在A中实现任何此类方法。它也不是从超类(UIViewController)继承的,因为在实现init(coder:)时,您有效地销毁了所有继承的初始化器。

因此,如果您想说B(),则必须自己在A中显式实现init(),如下所示:

class A: UIViewController {

    public var name = String()

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

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        name = "This is a test"
    }
}