问题是init(customView:)
调用init()
.
而且由于您有一个必需的初始化程序,因此您不再继承init()
. 因此,您必须实现它,即使只是调用super.init()
.
然后,您将面临必须初始化 ininit()
和 in 中的所有属性的(轻度)烦恼init(text:)
。但是,在您的特定情况下,首先不需要在初始化程序中执行此操作。我会这样写你的课:
class LabelBarButtonItem: UIBarButtonItem {
let label = UILabel(frame: CGRectZero)
init(text: String) {
super.init(customView: self.label)
self.label.text = text
self.label.tintColor = UIColor.grayColor()
}
private override init() {
super.init()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
在您的评论中,您问:
但是现在如果我重写 init(),我的类的客户可以通过调用 LabelBarButtonItem() 创建一个无效的 LabelBarButtonItem 实例
正确的。这就是为什么我将init()
覆盖标记为private
. 请注意,仅当此类在文件中单独关闭时才有效。
另一种可能性是将所有初始化程序(包括init(coder:)
)标记为convenience
. 现在你继承init()
了,整个问题就消失了。然而,这引入了另一组问题,留给读者作为练习。
澄清一下,我认为这整个情况是 Swift 中的一个错误。IIRC,直到最近的修订版(Xcode 6.1?),它才表现得像这样。您被super.init(customView:)
称为您的 init()
. 你可以争辩说那是错误的。你有一个很好的错误报告用例。此外,运行时的崩溃似乎是错误的行为;如果这会发生,为什么编译器不阻止我们?也许其他人可以证明 Swift 在这种情况下所做的事情是正确的。我只是想解释一下。
编辑此答案来自 2014 年,旨在解决当时存在的错误。在现代 iOS 版本中,该错误已消失,您可以这样说:
class LabelBarButtonItem: UIBarButtonItem {
init(text: String) {
let label = UILabel(frame: .zero)
label.text = text
label.sizeToFit()
super.init()
self.customView = label
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
或者你可以这样说:
class LabelBarButtonItem: UIBarButtonItem {
convenience init(text: String) {
let label = UILabel(frame: .zero)
label.text = text
label.sizeToFit()
self.init(customView: label)
}
}
在最初提出问题的那一刻,这两者都不可能。