简体   繁体   English

Swift:属性未在super.init调用时初始化

[英]Swift: Property not initialized at super.init call

I am making a little custom keyboard and I have a set of variables inside the class that need to be initialized inside the 'override init()' as can be seen below: 我正在制作一个小的自定义键盘,我在类中有一组需要在'override init()'中初始化的变量,如下所示:

class KeyboardViewController: UIInputViewController {

var button01: CharacterButton
var button02: CharacterButton
...

and

override init()   {

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

        super.init()
}

In addition to that I have also added the following code, as it is apparently required since Xcode 6 beta 5: 除此之外,我还添加了以下代码,因为从Xcode 6 beta 5开始显然需要它:

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

But that last snippet of code results in an error saying: 但最后一段代码导致错误说:

Property 'self.button01' not initialized at super.init call 属性'self.button01'未在super.init调用时初始化

Why would this happen when I have already initialized 'button01' and called the 'super.init()' inside the former 'override init()' function? 当我已经初始化'button01'并在前'覆盖init()'函数中调用'super.init()'时,为什么会发生这种情况? This is driving me nuts. 这让我疯了。

init(coder:) and init() are two different designated initialisers. init(coder:)init()是两个不同的指定初始化器。 You have few options here. 你在这里几乎没有选择。 The best one would be to initialise your properties in-place. 最好的方法是就地初始化您的房产。

class KeyboardViewController: UIInputViewController {

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

EDIT: 编辑:

Removed initializers from the above code. 从上面的代码中删除了初始值设定项。 If all the properties are initialised in-place, there is no need for overriding any initializer. 如果所有属性都就地初始化,则无需覆盖任何初始化程序。 All of them will simply be inherited automatically (including init(coder:) ). 所有这些都将被自动继承(包括init(coder:) )。


Or you can do something like this, if your class is never going to be created from nibs (including storyboards: 或者你可以做这样的事情,如果你的类永远不会从笔尖创建(包括故事板:

    class KeyboardViewController: UIInputViewController {

    ...

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

I don't like this solution, as it breaks the superclass' promise about implementing NSCoding, but it 'works'. 我不喜欢这个解决方案,因为它打破了超类对实现NSCoding的承诺,但它“有效”。 Finally, you can make your properties be implicitly unwrapped optionals. 最后,您可以使您的属性成为隐式解包的选项。

class KeyboardViewController: UIInputViewController {

    var button01: CharacterButton!
    var button02: CharacterButton!

    ...
}

But if you do that, your init(coder:) will become unsafe, so it's better to throw fatalError from there and stick to non-optionals. 但是如果你这样做,你的init(coder:)将变得不安全,所以最好从那里抛出fatalError并坚持使用非选项。

This happens because if the class is created with the second initializer 这是因为如果使用第二个初始化程序创建类

init(coder aDecoder: NSCoder!)

then your variables button01 and button02 are never initialized. 那么你的变量button01和button02永远不会被初始化。 And since they are not optionals, the compiler does not allow this. 由于它们不是选项,因此编译器不允许这样做。

You could change the second initializer to something like this: 您可以将第二个初始化程序更改为以下内容:

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

Or you could initialize you variables when they are declared: 或者,您可以在声明变量时初始化变量:

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

If you're not interested in implementing init(coder:) you should throw an error. 如果你对实现init(coder:)不感兴趣,你应该抛出一个错误。

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

I am not sure if the system invokes init(coder:) for UIInputViewController sub-classes however. 我不确定系统是否为UIInputViewController子类调用init(coder:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM