2009-10-26 7 views
3

La question fondamentale est "combien de UIViewControllers pouvez-vous pousser sur la pile de navigation?" sans provoquer d'avertissement de mémoire ou de gagner une fin de chien de garde.iPhone - UINavigationController, réutilisation des vues?

Supposons que j'ai une application qui est essentiellement une base de données pour trois entités où chacun peut avoir une relation avec une autre entité, et la relation est présentée sur une UIViewController. Les utilisateurs peuvent suivre ces relations et chacun d'eux amène un nouveau contrôleur - Si les entités sont A, B et C et A-> B-> C-> B-> C-> A, alors chaque type de vue est sur la pile deux fois . Je comprends comment pousser et sauter, comment repousser vers un contrôleur particulier, et je pense que plutôt que d'étendre indéfiniment la pile de navigation, il peut être préférable de réutiliser un contrôleur de vue dans la pile de navigation. Pour ce faire, chaque fois que je voulais un FirstEntityViewController, je pouvais scanner la pile de navigation pour trouver un objet où [self isKindOfClass:[FirstEntityViewController class]]; puis appeler des méthodes conçues pour redéfinir cette vue pour ce que je veux voir - juste rafraîchir les données dans le même comme vous le faites en réutilisant un UITableViewCell.

Ceci est bien, sauf pour l'effet qu'elle pourrait avoir sur le NavigationController. Si j'utilise UINavigationController:popToViewController:animated: je pense qu'il va jeter tout ce qui précède la vue je popping à, y compris le point de vue que l'utilisateur attend à trouver sur les écoutes « Retour » dans la barre de navigation. Alors l'utilisateur tape une relation, tape en arrière et va "hein?"

Si je supprime le contrôleur correspondant de la pile de navigation, puis le place en haut de la pile, le comportement retour reste OK tant que l'utilisateur ne revient pas aussi loin que l'instance de FirstEntityViewController déplacée ou encore la navigation semblera incohérente.

Est-ce que la bonne solution est de retirer le contrôleur de la pile et de conserver une place dans la pile de sorte que lorsque le contrôleur réutilisé est déplacé, il peut être replacé d'où il vient? Devrais-je conserver ma propre liste de types de vue et d'affichage des données afin que je puisse remplacer la vue en dessous de la vue sur le point d'apparaître, en gardant une longueur d'avance sur la navigation arrière?

Ou est-ce juste être trop compliqué? Yat-il pas besoin de se soucier même de cette situation, car le système d'exploitation réutilise la plupart des contrôleurs de vue de la même manière que UITableViewCells sont réutilisés, et il n'y a pas de véritable effet mémoire ou la performance d'avoir une pile de navigation 50 profondeur?

+0

On dirait qu'il y a deux questions: 1) combien de choses peuvent être sur la pile, et 2) une chose donnée peut-elle être sur la pile plus d'une fois? Droite? –

+0

Sorte de. Combien de choses peuvent être sur la pile, définitivement. Est-ce qu'une chose donnée peut être sur la pile plus d'une fois? Je suis assez sûr que la réponse est oui, je suis juste préoccupé par l'impact (c'est-à-dire didReceiveMemoryWarning) de l'autoriser. La solution consiste peut-être à attendre cet avertissement de mémoire, puis à rechercher les entrées de pile à tuer, comme tout ce qui précède la dernière vue "importante". –

Répondre

4

Les instances de ViewController restent dans la pile de UINavigationController, mais toute vue à l'exception de la vue de dessus peut être déchargée à tout moment (le contrôleur de vue est averti via le message viewDidUnload). En d'autres termes, les vues sous la vue de dessus ne traînent pas et seront éventuellement déchargées dans des conditions de faible mémoire, vous n'avez donc pas besoin d'essayer de réutiliser vos contrôleurs de vue.

+0

Qu'arrive-t-il à la navigation lorsque les vues sont déchargées - le lien passe devant la vue manquante et permet toujours le retour ou le retour cesse-t-il d'être une option? –

+1

Non. Lorsqu'il est temps que la vue apparaisse à nouveau, elle est rechargée via les messages loadView et viewDidLoad. Vous pouvez tester cela dans le simulateur en simulant une condition de mémoire faible. – Darren

0

dernier, je vous vérifié ne pouvez pas pousser un viewcontroller qui est déjà sur une pile de NavController revenir sur elle à nouveau. Vous devrez créer un nouveau viewcontroller et le pousser sur la pile, et chaque bouton de retour retirera celui-ci de la pile. Le mieux que vous puissiez faire est de créer un cache des viewcontrollers et de les distribuer selon vos besoins, à condition qu'ils soient supprimés de la pile du contrôleur de nav. Mais il ne vous achètera probablement pas beaucoup d'économies de mémoire. Les vues UITableView sont un peu différentes car il n'y a qu'un nombre relativement petit de cellules visibles à un moment donné et dès que la cellule est hors écran, elle est supprimée et renvoyée dans le pool. Si vous pouvez garantir que la longueur maximale de votre chaîne est fixe, vous pouvez utiliser un schéma de fenêtrage similaire. Si ce n'est pas le cas, vous devrez peut-être rester vigilant et être vigilant à l'idée de libérer de la mémoire dès que possible.

Questions connexes