2008-10-30 5 views
6

Alors oui, je suis un gars de Java dans ce monde d'iPhone fou. Quand il s'agit de gestion de la mémoire, je n'ai pas encore une très bonne idée de ce que je fais.Comment gérer la mémoire UIViewControllers avec un contrôleur de navigation?

j'ai une application qui utilise un contrôleur de navigation, et quand il est temps de passer à la vue suivante je code qui ressemble à ceci:

UIViewController *myController = [[MyViewController alloc] initWithNibName:@"MyView" 
                    bundle:[NSBundle mainBundle]; 
[[self navigationController] pushViewController:myController animated:YES]; 

Or, selon la règle fondamentale d'Apple sur la gestion de la mémoire

vous prenez possession d'un objet si vous créez à l'aide d'une méthode dont le nom commence par « alloc » ou « nouveau » ou contient « copie » (par exemple, alloc, newObject ou mutableCopy), ou si vous envoyez c'est un retain message. Vous êtes responsable de la renonciation à la propriété des objets que vous possédez en utilisant release ou autorelease. Toute autre fois que vous recevez un objet, vous ne devez pas le libérer.

Pour moi, cela signifie que je publierai myController, ou en lui donnant un message autorelease. Mais, chaque fois que j'essaye de le faire, mon application finit par s'écraser alors que je pousse et ouvre les vues de la pile. Cela ne me paraissait pas normal, mais en exécutant Instruments, il prétend que je n'ai pas de fuites de mémoire.

Je ma question est

  1. que je fais ce droit?
  2. Le contrôleur de navigation prend-il en charge MyViewController, expliquant l'absence de fuite de mémoire?
  3. Devrais-je attribuer myController à une variable d'instance dans mon ViewController racine? Dans ce cas, il serait marqué conserver et je publierait dans la méthode dealloc de racine

Répondre

3

@Ben Gottlieb Pourquoi avez-vous besoin de libérer automatiquement avant de le pousser? Conserver compte à l'allocation d'objets est 1, autorelease avant ou après avoir poussé n'affecte pas le conserver nombre, mais autoreleasing généralement une question de style est appliqué AFER objet alloc/init:

[[[object alloc] init] autorelease]; 

@bpapa,

2) En poussant, le contrôleur de navigation conservera le contrôleur de vue. Plus tard, lorsque cette vue est retirée de la pile du contrôleur de navigation, le contrôleur de navigation la relâche.

3) À moins qu'il n'y ait une raison explicite de conserver cette vue, vous ne devriez pas l'assigner à une variable d'instance. En général, vous voulez que vos opinions n'existent que tant que vous en avez besoin.

+0

Je ne faisais que mettre en contraste l'utilisation de l'autorelease avec la libération. Vous pouvez autoelease avant ou après, ce n'est pas grave, mais si vous libérez, vous devez le faire après. –

9

Le problème est (le plus probable) vous libérer votre viewController avant le contrôleur de navigation a une chance de revendiquer la propriété. Il y a deux façons de contourner cela:

  • -release votre contrôleur après poussant au contrôleur Nav
  • -autorelease votre contrôleur avant pousser. Si vous faites cela, le NSAutoreleasePool actif (dont vous n'avez pas à vous soucier) prendra soin de libérer votre contrôleur plus tard.
Questions connexes