为什么 Swift UIView 子类在更新到 Swift 3.0 后会开始无限循环?
Why would a Swift UIView subclass with a convenience init() method start infinite looping after updating to Swift 3.0?
这是一个项目的一些代码,正如您在此处看到的,在 Swift 2.3 中运行良好。现在将项目升级到 Swift 3.0,这会在 self.init()
.
处产生无限循环
class MyView: UIView
{
fileprivate let foo: String
required init? ( coder aDecoder: NSCoder )
{
fatalError( "init( NSCoder ) has not been implemented" )
}
convenience init ()
{
self.init()
foo = "bar"
}
}
有人告诉我这在 Swift 2.3 中也应该有无限循环。很公平,我相信,我只能告诉你它没有,但我不知道为什么。 post - 中建议的可能解决方案没有用,因为:
有问题的convenience init()
方法真的很方便
初始化;
self.init( frame: )
生成构建时错误消息
Incorrect argument label in call (have 'frame:', expected 'coder:')
,和;
我没有 NSCoder
的实例可以传递给 self.init( coder: )
我决定改为这样做:
override init ( frame: CGRect )
{
foo = "bar"
super.init( frame: frame )
}
我对这个解决方案不满意,因为它意味着传递一个无用的框架,我稍后必须用约束覆盖它。如果有人有更好的解决方案,请提出建议。谢谢。
更新
感谢@Luca-D'Alberti 提供以上 "correct" 回答。
convenience init
应始终将初始化委托给超类的指定初始化程序,在本例中为 UIView
。不幸的是,我找到的唯一解决方案是这样做:
class MyView: UIView {
fileprivate let foo: String = "bar"
convenience init() {
self.init(frame: .zero)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
这是一个项目的一些代码,正如您在此处看到的,在 Swift 2.3 中运行良好。现在将项目升级到 Swift 3.0,这会在 self.init()
.
class MyView: UIView
{
fileprivate let foo: String
required init? ( coder aDecoder: NSCoder )
{
fatalError( "init( NSCoder ) has not been implemented" )
}
convenience init ()
{
self.init()
foo = "bar"
}
}
有人告诉我这在 Swift 2.3 中也应该有无限循环。很公平,我相信,我只能告诉你它没有,但我不知道为什么。 post -
有问题的
convenience init()
方法真的很方便 初始化;self.init( frame: )
生成构建时错误消息Incorrect argument label in call (have 'frame:', expected 'coder:')
,和;我没有
NSCoder
的实例可以传递给self.init( coder: )
我决定改为这样做:
override init ( frame: CGRect )
{
foo = "bar"
super.init( frame: frame )
}
我对这个解决方案不满意,因为它意味着传递一个无用的框架,我稍后必须用约束覆盖它。如果有人有更好的解决方案,请提出建议。谢谢。
更新
感谢@Luca-D'Alberti 提供以上 "correct" 回答。
convenience init
应始终将初始化委托给超类的指定初始化程序,在本例中为 UIView
。不幸的是,我找到的唯一解决方案是这样做:
class MyView: UIView {
fileprivate let foo: String = "bar"
convenience init() {
self.init(frame: .zero)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}