Question

J'ai une sous-classe de UITableViewController qui est instancié, selon l'endroit où il est utilisé, dans un NIB ou par code. Dans les deux cas, je veux faire la personnalisation dans la méthode d'initialisation. Est-ce que cela signifie que je dois mettre en œuvre à la fois initWithNibName:bundle: et initWithCoder:, et chaque méthode serait appeler ses super initialiseur respectifs?

Alors que je ne suis pas besoin de ce moment, si je veux aussi pouvoir instancier le contrôleur de vue avec initWithStyle:? Aurais-je besoin alors 3 différentes méthodes d'initialisation qui répliquent le même comportement?

Il semble que cela viole toute convention initialiseur désigné, comme il serait essentiellement 3 initializers distincts qui ne finissent pas d'appeler une méthode init commune. Ou est-il un moyen de créer un initialisateur désigné commun tout en soutenant les 3 différentes routes instancier?

Était-ce utile?

La solution

Ma confusion était fondée sur la croyance erronée que chaque classe doit avoir un seul initialiseur désigné. Ce n'est pas vrai, et dans le cas de UITableViewController il y a 3 initialiseurs désignés (pour autant que je peux dire):

  1. initWithStyle: déclaré localement
  2. initWithNibName:bundle: héritée de UIViewController
  3. initWithCoder: d'adopter le protocole NSCoding

Vous devez remplacer 1 ou plus de ceux-ci dans votre sous-classe selon la façon dont votre sous-classe s'instancié. Dans mon cas, je devais mettre en œuvre # 2 et # 3 depuis la classe peut être chargée à partir d'un NIB ou instancié via le code en référence à un NIB. (Je pense qu'il est rare que vous utilisez à la fois initWithStyle: et initWithNibName:bundle: pour une seule classe.)

J'ai trouvé Apple codage Directives pour Cocoa utile.

Autres conseils

En interne,

  • Le -initWithStyle: de UITableViewController appelle la -init de super puis réglez le Ivar de _tableViewStyle.
  • La -init de UIViewController appelle simplement -initWithNibName:bundle: avec des arguments par défaut.
  • UITableViewController ne pas override -initWithNibName:bundle:.

Par conséquent, si vous substituez -initWithNibName:bundle: alors -initWithStyle: adoptera le changement aussi. Bien sûr, pour jouer en toute sécurité (comme vous ne devriez pas compter sur les détails de mise en œuvre), passer outre les deux.

(Et pas besoin de passer outre -initWithCoder: à moins que vous les instances des Nations Unies / archiver.)

Pour clarifier, initWithStyle:, étant la seule initialiseur publié de UITableViewController dans la documentation, est son un initialiseur explicite désigné.

initWithNibName:bundle: est héritée de UIViewController et est l'initialiseur désigné pour cette classe. A ce titre, conformément aux directives de cacao, UITableViewController doit remplacer cette méthode (par sa mise en œuvre). Toutefois, cela ne fait pas un initialiseur désigné de UITableViewController.

initWithCoder: est, comme vous le soulignez, un initialiseur désigné implicite de NSCoding.

Mettre en œuvre:

- (void) viewDidLoad

et y faire votre initialisation du composant.

Il a l'avantage de ne faire l'initialisation lorsque la vue est en fait demandé.

Ou tout simplement faire une méthode de configuration séparée invoquée par tous les initialiseurs.

Un plus des messages ci-dessus que -initWithCoder de référence:

Si vous avez ajouté ajouté le contrôleur en vue de son parent par le constructeur d'interface (par exemple: si le contrôleur de vue est connecté à un contrôleur de barre d'onglets dans le constructeur d'interface), alors vous devez passer outre -initWithCoder

.

(-. InitWithNibName ne sera appelé lors de la création du contrôleur de vue programme)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top