Ios 为什么我必须为我的programatic UIViewController子类的init(coder aDecoder)声明相同的必需但未实现的初始值设定项?
也许只是我,但我发现斯威夫特的某些方面。。。至少可以说是迟钝 我大部分时间不使用Interface Builder,因为我喜欢使用Ios 为什么我必须为我的programatic UIViewController子类的init(coder aDecoder)声明相同的必需但未实现的初始值设定项?,ios,swift,uiviewcontroller,designated-initializer,Ios,Swift,Uiviewcontroller,Designated Initializer,也许只是我,但我发现斯威夫特的某些方面。。。至少可以说是迟钝 我大部分时间不使用Interface Builder,因为我喜欢使用PureLayout。所以我希望创建一个UIViewController子类,比如PureViewController,它有一个方便的init,没有参数: class PureViewController : UIViewController { init() { super.init(nibName: nil, bundle: nil)
PureLayout
。所以我希望创建一个UIViewController
子类,比如PureViewController
,它有一个方便的init
,没有参数:
class PureViewController : UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
}
}
但这并不好,因为XCode告诉我还必须实现init(coder-aDecoder:NSCoder)
。好的,没关系!这就是我创建这个类的原因——所以我不必再为子类做这个了
class PureViewController : UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
好吧,现在我不明白了
我定义了一个子类,SomePureViewController:PureViewController
,带有初始值设定项init(viewModel:icrackerviewmodel)
class SomePureViewController : PureViewController {
init(viewModel:ICrackersViewModel) {
super.init()
}
}
但它仍然希望我在王国到来之前定义同一个愚蠢的初始值设定项
class SomePureViewController : PureViewController {
init(viewModel:ICrackersViewModel) {
super.init()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
现在我明白了这个想法——在我的子类中没有init(decoder)
,即使它是在其父类中定义的
也许我一直在用UIViewController
处理这个问题,以前从未注意到
我的问题如下:
我认为这是一个迅速的问题,无法避免。我们都讨厌这个空的致命错误初始值设定项。由于初始值设定项用
required
关键字标记,所有子类都必须实现该初始值设定项,并且它们还必须在实现中指定required
,以便它们的子类也需要实现它
所需的初始值设定项
将所需的修饰符写在
类初始值设定项的定义,以指示
类必须实现该初始值设定项
您还必须在所需初始值设定项的每个子类实现之前写入所需的修饰符,以表明初始值设定项要求适用于链中的其他子类。”
这是自1.0以来Swift语言的一部分,不太可能改变
这个问题实际上与在UIViewController类定义中使用
required
关键字有关。理论上这是可以改变的,但我认为这是不可能的 关键是,只要知道基类类型,就可以初始化可能派生的类
让我们假设一个基类
class Base {
let value: Int
required init(value: Int) {
self.value = value
}
}
和一个函数
func instantiateWith5(cls: Base.Type) -> Base {
return cls.init(value: 5)
}
那我们就可以做了
let object = instantiateWith5(Base.self)
现在如果有人定义了一个派生类
class Derived: Base {
let otherValue: Int
init() {
otherValue = 1
super.init(value: 1)
}
required init(value: Int) {
fatalError("init(value:) has not been implemented")
}
}
我们至少可以打电话
let object2 = instantiateWith5(Derived.self)
违反LSP,但这是代码的问题,而不是语言的问题
Swift必须保证初始值设定项使您的对象处于初始化状态,即使它们是从基对象派生的,所以我想更改它将是一件坏事。如果您想定义一个不可反序列化的UIViewController,从而违反LSP,这是您的决定,但不要期望语言在这方面支持您。回答得好。我将需要更多的玩转它来真正“得到它”,但我仍然觉得这是一个问题,只是出于某种原因,斯威夫特。或者更确切地说,可能是
必需的是只有swift才具备的功能。