J'ai une sous-classe d'UIView qui est instanciée dans un fichier XIB. J'en ai besoin pour faire une certaine initialisation (Paramètres de variables et créer une sous-vision). P>
Cependant, je n'ai pas toujours instancier cette vue via Interface Builder. Je le fais de manière programmatique aussi. Dans les deux cas, l'initialisation doit être la même. P>
Mon initialiseur désigné est La question est; Où puis-je exécuter l'initialisation? strong> p>
Puisque je dois l'exécuter dans 2 endroits différents, j'ai pensé que je dois le refroidir dans une méthode distincte d'initialisation code> (ou quelque chose comme ça) et l'appelez à partir de mais lors du chargement d'IB, les deux initwithvalues: code>. p>
initwithvalues: < / code>. p>
initwithcoder: code> et
ewakefromnib code> sont appelés. De quelle méthode dois-je appeler
initialiser code>? Ou dois-je appeler
initwithvalues: code> à partir de
initwithcoder: code> et ne rien faire dans
ewakefromnib code>? P>
3 Réponses :
Cela dépend de ce que vous devez initialiser. Dès que ewakefromnib code> est appelé, tous les points de vente et les connexions d'action de votre vue sont établis qui n'est pas le cas dans
initwithcoder: code>. Donc, si vous avez besoin de vous fier à ces connexions, utilisez ewakeffromnib. Sinon, vous pouvez effectuer toute votre initialisation dans
initwithcoder: code>. P>
Vous devez utiliser Quelque chose comme ça devrait fonctionner pour l'initialisation:;) p> initwithframe: code> lors de l'initialisation des vues (puisqu'il s'agit de l'initialiseur désigné). Par conséquent, si vous avez
initwithvalues: code> Assurez-vous d'appeler
initwithframe: code> de celui-ci.
- (void)initialize{
//init your ivars here
}
- (id)initWithCoder:(NSCoder *)aCoder{
if(self = [super initWithCoder:aCoder]){
[self initialize];
}
return self;
}
- (id)initWithFrame:(CGRect)rect{
if(self = [super initWithFrame:rect]){
[self initialize];
}
return self;
}
N'est-il pas "faux" d'appeler deux initialiseurs différents de la superclasse? Je ne devrais pas appeler l'initialisateur désigné de ma sous-classe ( initwithvalues: code>) à partir de
initwithcoder: code>?
N'est-il pas "faux" d'appeler deux initialiseurs différents de la superclasse? → Non parce que seul l'un d'entre eux sera appelé. Je ne devrais pas appeler l'initialisateur désigné de ma sous-classe (initwithvithavalues :) d'InitwithCoder:? → partiellement oui. InitwithCoder: s'attend à ce que vous soyez unarchive de l'objet. C'est pourquoi nous appelons [Super InitwithCoder]; En faisant cela, la vue sera initialisée. Maintenant, vous n'avez besoin que d'introduire d'autres ivars, quelque chose que je suppose que vous faites à l'intérieur de la méthode d'initialisation.
Malheureusement, les réponses ci-dessus ne prennent pas en compte ces choses: - (NOID) AwakafterUtilisateurCoder - et le fait qu'elle est appelée après que tout soit créé par le codeur (une fois pour chaque point de vue XIB). Awakefromnib souffre du même destin, j'ai remarqué. (La raison pour laquelle j'ai trouvé cela)
Un autre problème d'initialisation est que l'initwithcoder et l'initwithframe peuvent être évités pour des vues personnalisées. Et s'ils sont appelés, le chargement paresseux (mais pas aussi important sur les vues elles-mêmes) signifie que vous «pourrait» être en mesure de modifier des valeurs. Je crois que je l'ai fait dans InitwithCoder, mais si vous initialisez ensuite les valeurs dans Awakefromnib, c'est annulé au moins une fois. P>
Je suis allé jusqu'à: P>
- (void) awakeFromNib (or didMoveToSuperView); { BOOL called = NO; if(!called) { called = YES; } }
Je pense que didmovetosuperview code> est un très bon endroit pour le faire pour la plupart des vues - cela couvrira une instanciation manuelle et de la nib sans plusieurs méthodes init. Pas si bon si vous avez besoin de la vue pour effectuer une logique avant qu'il ne soit à l'écran, mais si vous faites cela, il y a probablement quelque chose de mal ...
Oui, c'est en fait ce que j'ai eu recours à finalement, mais même il a une faille. Quand il est supprimé et que son superview est nul, on l'appelle également. Pas bon pour réarranger, j'ai donc ajouté un test pour "si superview nil" beaucoup comme le test appelé. Faites attention à ça! Merci pour la réponse: D