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

Ios 使用所需的编码器初始化初始化子类UIViewController-怎么办?,ios,swift,Ios,Swift,这可能是迄今为止最愚蠢的问题——但我在使用定制的必需编码器初始值设定项初始化子类视图控制器时遇到了问题(特别是使用QRCoder pod;为了不公开我不拥有的代码,我将在本例中使用示例类) 这里是要点 class A: UIViewController { public var name = String() required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder)

这可能是迄今为止最愚蠢的问题——但我在使用定制的必需编码器初始值设定项初始化子类视图控制器时遇到了问题(特别是使用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
参数,我到底要在里面放什么?我试着用一个空的(?)n代码填充它,就像这样

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!'
我曾尝试向添加一个方便的初始值设定项(出于某种原因,我必须运行
self.init
而不是
super.init
),但这样做会导致
EXC\u BAD\u ACCESS\u错误

我需要向
init:(coder)
实例提供什么才能。。。事情进展顺利吗

我需要向
init:(coder)
实例提供什么才能。。。事情进展顺利吗

没什么。停止思考
init(编码者:)

这是实际的问题。当您说
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"
    }
}

当然,您仍然会遇到这样一个问题:这一行完全是胡说八道:
按钮(self,action:#选择器(buttonTapped(:)),for:.touchupinder)}
但这是另一个问题。啊哈!明亮的将逻辑从所需的init移动到普通init确实做到了这一点。还有,re:那一行-是的,我错过了
addTarget
函数,太棒了!