Je ne peux pas ajouter de méthode init à la classe UIViewController suivante. J'ai besoin d'écrire du code dans la méthode init. Dois-je écrire la méthode init (codeur)? Même lorsque j'ajoute les méthodes de codage et de décodage, des erreurs se produisent encore. J'ai également essayé d'utiliser la méthode init sans aucun paramètre, mais cela ne semble pas non plus fonctionner.
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nil, bundle: nil)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
...
...
}
Si j'appelle la méthode super.init () sans paramètre, l'erreur est "Doit appeler un initialiseur désigné de la super classe" et si je transmets le paramètre nib and bundle, l'erreur est "Requis pour l'initialisateur d'initialisation (codeur)".
Même si j'ajoute init (codeur) et init (décodeur), cela ne fonctionne pas.
J'ai utilisé:
convenience init() {
self.init(nibName:nil, bundle:nil)
}
Certaines personnes ont suggéré:
convenience init(){
self.init()
}
Mais cela vous donne une boucle infinie.
Toutes ces réponses sont des demi-réponses. Certaines personnes rencontrent des boucles infinies dans les publications liées car elles n’ajoutent que le convenience init()
(elle s’appelle de manière récursive si vous ne fournissez pas de méthode init()
distincte à invoquer), tandis que d'autres personnes négligent d'étendre la super-classe. Ce format combine toutes les solutions pour résoudre complètement le problème.
// This allows you to initialise your custom UIViewController without a nib or bundle.
convenience init() {
self.init(nibName:nil, bundle:nil)
}
// This extends the superclass.
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
// This is also necessary when extending the superclass.
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented") // or see Roman Sausarnes's answer
}
Edit: De même, si vous souhaitez initialiser des propriétés de classe à l'aide de paramètres passés dans votre méthode convenience init()
sans toute la fonction init()
méthodes se plaignant, vous pouvez alors définir toutes ces propriétés comme des options implicitement non enveloppées, ce qui est un motif tilisé par Apple eux-mêmes .
Vous devez remplacer l'initialiseur init(nibName:bundle:)
, et fournir l'initialiseur init(coder:)
requis et initialiser tap
dans les deux:
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
print("init nibName style")
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
// note slightly new syntax for 2017
required init?(coder aDecoder: NSCoder) {
print("init coder style")
super.init(coder: aDecoder)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
...
...
}
Assurez-vous également, lors de l'appel de l'initialiseur de superclasse, que vous ne transmettez pas simplement nil
pour les nibName
et bundle
. Vous devriez laisser passer tout ce qui a été transmis.
Vous pouvez simplement créer un initialiseur de commodité à la place. Les initialiseurs de commodité ne remplacent pas init (), ils l'appellent simplement pour faciliter les choses.
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
convenience init(){
self.init()
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
}
Je pense que vous devez ajouter
required init(coder aDecoder: NSCoder) {
print("init coder")
super.init(coder: aDecoder)
}
ou
convenience init() {
self.init()
}
Vous devez aussi écrire init. Ne l'enlève pas
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nil, bundle: nil)
}
J'espère que ça aide
Je suis tombé sur cette question de vous demandé long chemin en arrière. Mais personne n'a fourni de réponse élémentaire à la question. C'est un élément de base de Swift) qui: - La sous-classe doit initialiser ses variables avant que l'initialisation de sa super-classe ne soit terminée.
Par conséquent, Ankit Goel a mentionné le crash: - "Doit appeler un initialiseur désigné de la superclasse"
Par conséquent, le code mis à jour serait: -
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
print("init nibName style")
self.tap = nil
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:")))
}
required init?(coder aDecoder: NSCoder) {
print("init coder style")
self.tap = nil
super.init(coder: aDecoder)
tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:")))
}}