Reputation: 359
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:
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:
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
Why would this happen when I have already initialized 'button01' and called the 'super.init()' inside the former 'override init()' function? This is driving me nuts.
Upvotes: 10
Views: 11701
Reputation: 4823
init(coder:)
and init()
are two different designated initialisers. 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:)
).
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'. 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.
Upvotes: 8
Reputation: 59506
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. 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")
Upvotes: 4
Reputation: 21003
If you're not interested in implementing init(coder:)
you should throw an error.
required init(coder aDecoder: NSCoder!) {
fatalError("use init() method")
}
I am not sure if the system invokes init(coder:)
for UIInputViewController
sub-classes however.
Upvotes: 0