【问题标题】:Swift: Property not initialized at super.init callSwift:在 super.init 调用时未初始化属性
【发布时间】:2014-10-09 17:02:07
【问题描述】:

我正在制作一个小自定义键盘,我在类中有一组变量,需要在“覆盖 init()”中进行初始化,如下所示:

class KeyboardViewController: UIInputViewController {

var button01: CharacterButton
var button02: CharacterButton
...

override init()   {

        //Initialize buttons and assign attributes
        button01 = CharacterButton.createButton("Q", labelOfButton: "Q")
        button02 = CharacterButton.createButton("W‎", labelOfButton: "W")

        super.init()
}

除此之外,我还添加了以下代码,因为它显然是自 Xcode 6 beta 5 以来所必需的:

required init(coder aDecoder: NSCoder!) {
    super.init(coder: aDecoder)
}

但是最后的 sn-p 代码会导致错误提示:

属性 'self.button01' 未在 super.init 调用时初始化

当我已经初始化了 'button01' 并在之前的 'override init()' 函数中调用了 'super.init()' 时,为什么会发生这种情况?这让我发疯了。

【问题讨论】:

  • 尝试在您的 button01... 代码之前调用 super.init()。
  • 我不能,这样做会给我另一个错误说:“self.button01 not initialized at super.init call”,本质上是说我必须先初始化按钮,然后再调用super。 init() 就像我在原始帖子中所做的那样。

标签: ios xcode swift initialization overriding


【解决方案1】:

如果您对实现 init(coder:) 不感兴趣,您应该抛出一个错误。

required init(coder aDecoder: NSCoder!) {
    fatalError("use init() method")
}

我不确定系统是否为UIInputViewController 子类调用init(coder:)

【讨论】:

    【解决方案2】:

    这是因为如果类是使用第二个初始化程序创建的

    init(coder aDecoder: NSCoder!)
    

    那么你的变量 button01 和 button02 永远不会被初始化。而且由于它们不是可选项,编译器不允许这样做。

    您可以将第二个初始化程序更改为如下内容:

    required init(coder aDecoder: NSCoder!) {
        button01 = CharacterButton.createButton("Q", labelOfButton: "Q")
        button02 = CharacterButton.createButton("W‎", labelOfButton: "W")
        super.init(coder: aDecoder)
    }
    

    或者您可以在声明变量时对其进行初始化:

    var button01 = CharacterButton.createButton("Q", labelOfButton: "Q")
    var button02 = CharacterButton.createButton("W‎", labelOfButton: "W")
    

    【讨论】:

      【解决方案3】:

      init(coder:)init() 是两个不同的指定初始化器。您在这里几乎没有选择。最好的方法是就地初始化您的属性。

      class KeyboardViewController: UIInputViewController {
      
          var button01 = CharacterButton.createButton("Q", labelOfButton: "Q")
          var button02  = CharacterButton.createButton("W‎", labelOfButton: "W")
      }
      

      编辑:

      从上述代码中删除了初始化程序。如果所有属性都已就地初始化,则无需覆盖任何初始化程序。所有这些都将简单地自动继承(包括init(coder:))。


      如果你的课程永远不会从 nibs 创建(包括故事板:

          class KeyboardViewController: UIInputViewController {
      
          ...
      
          required init(coder aDecoder: NSCoder!) {
              fatalError("This class doesn't support NSCoding.")
          }
      }
      

      我不喜欢这个解决方案,因为它违反了超类关于实现 NSCoding 的承诺,但它“有效”。最后,您可以使您的属性成为隐式展开的选项。

      class KeyboardViewController: UIInputViewController {
      
          var button01: CharacterButton!
          var button02: CharacterButton!
      
          ...
      }
      

      但如果你这样做,你的init(coder:) 将变得不安全,所以最好从那里抛出fatalError 并坚持使用非可选参数。

      【讨论】:

        猜你喜欢
        • 2020-07-06
        • 2021-12-22
        • 1970-01-01
        • 2014-07-24
        相关资源
        最近更新 更多