57 votes

Quelqu'un peut-il expliquer le processus de naissance d'un UIViewController (quelle méthode suit quelle méthode) ?

Il y a de nombreuses méthodes à surcharger, comme initWithNibname :, awakeFromNib, loadView, viewDidLoad, viewDidAppear :, et je n'arrive pas à décider dans quel ordre ces méthodes sont appelées.

Je ne fais que remplacer l'un d'entre eux "par cœur".

Une explication détaillée ?

173voto

e.James Points 51680

Il y a beaucoup de choses qui se passent dans les coulisses avec Gestion des vues et des viewController en Cocoa .

1. L'objet viewController

Dans sa forme la plus simple, un viewController est un objet contrôleur générique. Lorsqu'il est alloué et initialisé pour la première fois, aucun objet de vue ne lui est associé. La vue n'est instanciée que lorsque (et si) elle est requise. Ainsi, sans tenir compte de la vue, le cycle de vie d'un viewController est le même que celui de tout autre objet :

UIViewController * myVC = [[UIViewController alloc] initWith...];
...
[myVC release];

L'initialisateur désigné pour les viewControllers est -initWithNibname:bundle: . Si vous spécifiez un nib, le viewController peut automatiquement charger sa vue à partir de ce nib et connecter les IBOutlets que vous avez définis (voir ci-dessous pour plus de détails).

2. Chargement et déchargement de la vue

Un viewController chargera sa vue selon les besoins. Cela se produit généralement lorsque le -view est appelée pour la première fois, et peut se produire à n'importe quel moment dans votre programme, selon la façon dont vous initialisez votre interface utilisateur. La vue peut également être détruite et rechargée plusieurs fois au cours de la durée de vie de votre programme, toujours en fonction de la façon dont vous gérez votre interface utilisateur. Lorsque le viewController a identifié que sa vue est nécessaire mais n'est pas encore chargée, la fonction -loadView sera appelée. Le flux de messages de base ressemble à ceci :

view
  loadView
  viewDidLoad

Notez que si vous remplacez l'option -view méthode, -loadView et viewDidLoad ne sera pas appelé automatiquement. Si vous remplacez -loadView vous doit définissent les paramètres du viewController view propriété. Sinon, le prochain appel à -view déclenchera à nouveau le processus de chargement.

La vue peut également être déchargée à tout moment pendant la durée de vie de votre programme, en définissant simplement l'attribut view à la propriété nil . L'implémentation par défaut de -didReceiveMemoryWarning le fera automatiquement, tant que la vue n'a pas de vue supérieure (c'est-à-dire si elle ne fait pas partie de la hiérarchie des vues actives). Le flux de messages est le suivant :

view = nil
   viewDidUnload

2a. Chargement programmé de la vue

Si vous choisissez d'ignorer -loadView Dans le cadre d'un projet, vous pouvez créer une vue, des sous-vues, d'autres viewControllers et toutes les connexions entre ces objets de la manière qui vous convient. Bien entendu, cela signifie que vous êtes également responsable de la gestion de la mémoire pour les objets que vous créez. Si votre sous-classe surcharge -loadView il doit être initialisé en utilisant nil pour les deux nibName et bundle .

2b. Chargement de la vue à partir d'une plume

Si vous utilisez un fichier nib, l'implémentation par défaut de la fonction -loadView ouvrira automatiquement ce fichier nib, instanciera ses objets, ajoutera toutes les connexions entre eux et s'occupera de la gestion de la mémoire pour vous.

Les choses sont un peu plus délicates avec les fichiers nib, car il se passe beaucoup de choses en coulisse. Le site -awakeFromNib est appelée pour tout objet qui est instancié lorsqu'un fichier nib est chargé, et il n'y a aucune garantie que les autres objets du fichier nib auront été entièrement chargés lorsqu'il est appelé.

3. Affichage des vues

-viewWillAppear: , -viewDidAppear: , -viewWillDisappear: et -viewDidDisappear: ne sont appelées que lorsque la vue est affichée ou masquée à l'écran, notamment lors des transitions animées d'une vue à l'autre. Ces méthodes peuvent être appelées de nombreuses fois pendant la durée de vie de votre programme, au fur et à mesure que les vues sont échangées dans votre schéma de navigation.

4. Afficher la mise en page

Le site -layoutSubviews La méthode est pas partie de UIViewController . Il s'agit de UIView lorsque leurs limites ont été modifiées. Si vous utilisez un UIView dans votre programme, cette méthode peut être utilisée pour réaliser une mise en page personnalisée des vues secondaires au lieu de s'appuyer sur les méthodes de redimensionnement automatique par défaut de Cocoa.

5. Tout mettre en place

En raison de sa complexité, ce processus peut se dérouler de nombreuses façons différentes, mais une chronologie normale pourrait ressembler à ceci :

-[viewController initWithNibname:Bundle:]
-[viewController awakeFromNib]
-[viewController loadView]
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear]  // user navigated away
-[viewController viewDidDisappear]
...
-[viewController viewWillAppear]     // user navigated back
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear]  // user navigated away
-[viewController viewDidDisappear]
...
-[viewController setView:nil]        // memory warning, perhaps
-[viewController viewDidUnload]
...
-[viewController loadView]           // user navigated back
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...

37voto

Janusz Chudzynski Points 587

Je me suis penché sur la question récemment et j'ai créé un projet de test : https://github.com/Janek2004/ViewControllerTest

Exécutez le projet sur le simulateur iOS pour voir l'ordre d'exécution des méthodes de la sous-classe UIViewController. L'ordre peut être différent si nous utilisons un fichier Nib au lieu du storyboard ou si nous chargeons le contrôleur de vue de manière programmatique.

  1. -[ViewController initWithCoder :] Désarchiver les données d'une nib ou d'un storyboard

  2. -[ViewController awakeFromNib] Prépare le récepteur pour le service après qu'il ait été chargé à partir d'une archive Interface Builder ou d'un fichier nib ou d'un fichier nib.

  3. -[ViewController loadView] Vous ne devez jamais appeler cette méthode directement. Le contrôleur de vue appelle cette méthode lorsque sa propriété view est demandée mais est actuellement nulle. Cette méthode charge ou crée une vue et l'affecte à la propriété de la vue.

  4. -[ViewController viewDidLoad] Cette méthode est appelée après que le contrôleur de vues a chargé sa hiérarchie de vues en mémoire.

  5. -[ViewController viewWillAppear :] Cette méthode est appelée avant que la vue du récepteur soit sur le point d'être ajoutée à une hiérarchie de vues et avant que les animations soient configurées pour afficher la vue. que des animations soient configurées pour afficher la vue.

  6. -[ViewController viewWillLayoutSubviews] Appelé pour notifier le contrôleur de vue que sa vue est sur le point de mettre en page ses sous-vues. Lorsque les limites d'une vue changent, la vue ajuste la position de ses sous-vues. Votre contrôleur de vue peut remplacer cette méthode pour effectuer des changements avant que la vue ne dispose de ses sous-vues. avant que la vue ne mette en place ses sous-vues.

  7. -[ViewController viewDidLayoutSubviews] Appelé pour notifier au contrôleur de vue que sa vue vient de disposer ses sous-vues. Lorsque les changent pour la vue d'un contrôleur de vue, la vue ajuste l'élément positions de ses sous-vues, puis le système appelle cette méthode. Cependant, l'appel de cette méthode n'indique pas que les que les dispositions individuelles des sous-vues de la vue ont été ajustées. Chaque sous-vue de sous-vue est responsable de l'ajustement de sa propre disposition.

  8. -[ViewController viewDidAppear :] Notifie au contrôleur de vue que sa vue a été ajoutée à une hiérarchie de vues. Vous pouvez surcharger cette méthode pour effectuer des tâches supplémentaires associées à la présentation de la vue.

  9. -[ViewController viewWillDisappear :] Notifie au contrôleur de vue que sa vue est sur le point d'être retirée de la hiérarchie des vues. méthode est appelée en réponse à la suppression d'une vue de la hiérarchie des d'une vue. Cette méthode est appelée avant que la vue ne soit effectivement supprimée et avant que des animations ne soient configurées. et avant que toute animation ne soit configurée. Notifie au contrôleur de vue que sa vue a été ajoutée à une hiérarchie de vues. Vous pouvez remplacer cette méthode pour effectuer des tâches supplémentaires associées à la présentation de la vue. la présentation de la vue.

  10. -[ViewController viewDidDisappear :] Notifie au contrôleur de vue que sa vue a été supprimée de la hiérarchie des vues.

4voto

LordT Points 3342

De la documentation Apple UIViewController :

Lorsque vous définissez une nouvelle sous-classe de UIViewController, vous devez spécifier les vues qui seront gérées par le contrôleur. Il existe deux façons mutuellement exclusives de spécifier ces vues : manuellement ou à l'aide d'un fichier nib. Si vous spécifiez les vues manuellement, vous devez implémenter la méthode loadView et l'utiliser pour affecter un objet de vue Root à la propriété view. Si vous spécifiez des vues à l'aide d'un fichier nib, vous ne devez pas surcharger loadView, mais créer un fichier nib dans Interface Builder, puis initialiser votre objet contrôleur de vue à l'aide de la méthode initWithNibName:bundle :. La création de vues à l'aide d'un fichier nib est souvent plus simple car vous pouvez utiliser l'application Interface Builder pour créer et configurer vos vues graphiquement (par opposition à la programmation). Les deux techniques ont toutefois le même résultat final, à savoir créer l'ensemble approprié de vues et les exposer par le biais de la propriété view.

Du haut de ma tête :

  1. initWithNibname
  2. loadView (charger des trucs manuellement)
  3. viewDidiLoad
  4. viewDidAppear

aucune idée de l'endroit où entre layoutSubviews

1voto

hotpaw2 Points 40796

Je résous généralement cette question en plaçant un NSLog (ou des points d'arrêt) dans tous ces délégués, y compris le délégué de lancement de l'application, et en suivant l'ordre dans le débogueur.

1voto

Ram S Points 334
\-- This is related to view only:
-viewWillAppear:
-viewDidAppear: 
-viewWillDisappear: and 
-viewDidDisappear: 

are only called when the view is being displayed.

-viewController viewDidLoad
-viewController viewWillAppear
-viewController viewDidAppear

other methods

-viewController viewDidDisappear
-viewController viewWillDisappear 
-viewController viewDidUnload

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X