Pourquoi cette question a-t-elle été soulevée ? Eh bien, le fait est qu'elle a toujours Il a toujours été important (c'est-à-dire en Objective-C, depuis le jour où j'ai commencé à programmer Cocoa sous Mac OS X 10.0) de gérer les initialisateurs que votre classe n'est pas préparée à gérer. La documentation a toujours été très claire sur vos responsabilités à cet égard. Mais combien d'entre nous ont pris la peine de les remplir, complètement et à la lettre ? Probablement aucun d'entre nous ! Et le compilateur ne les faisait pas respecter ; tout était purement conventionnel.
Par exemple, dans ma sous-classe de contrôleur de vue en Objective-C avec cet initialisateur désigné :
- (instancetype) initWithCollection: (MPMediaItemCollection*) coll;
...il est crucial que l'on nous transmette une collection réelle d'éléments de média : l'instance ne peut tout simplement pas exister sans cela. Mais je n'ai pas écrit de "stoppeur" pour empêcher quelqu'un de m'initialiser avec une simple base init
à la place. I devrait en avoir écrit un (en fait, à proprement parler, j'aurais dû écrire une implémentation de initWithNibName:bundle:
l'initialisateur désigné par l'héritage) ; mais j'étais trop paresseux pour m'en préoccuper, car je "savais" que je n'initialiserais jamais incorrectement ma propre classe de cette façon. Cela laissait un trou béant. En Objective-C, quelqu'un peut appelez le "bare-bones init
en laissant mes ivars non initialisés, et nous sommes dans le pétrin sans pagaie.
Swift, merveilleusement, me sauve de moi-même dans la plupart des cas. Dès que j'ai traduit cette application en Swift, tout le problème a disparu. Swift crée effectivement un bouchon pour moi ! Si init(collection:MPMediaItemCollection)
est le seul initialisateur désigné déclaré dans ma classe, je ne peux pas être initialisé en appelant la fonction bare-bones init()
. C'est un miracle !
Ce qui s'est passé dans la graine 5 est simplement que le compilateur a réalisé que le miracle ne fonctionne pas dans le cas de init(coder:)
car en théorie, une instance de cette classe pourrait provenir d'une nib, et le compilateur ne peut pas l'empêcher - et lorsque la nib se charge, init(coder:)
sera appelé. Le compilateur vous oblige donc à écrire le stopper explicitement. Et il a raison.