这可能是迄今为止最愚蠢的问题-但是我在使用自定义的必需编码器初始化程序(特别是使用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)
实例提供什么才能使...正常运行?
答案 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"
}
}