2010-06-17 7 views
1

À différents moments pendant le flux de travail de mon application, j'ai besoin de montrer une vue. Cette vue nécessite beaucoup de mémoire, je veux donc qu'elle soit désallouée lorsqu'elle est rejetée par l'utilisateur. Donc, j'ai écrit le code suivant:Gestion de la mémoire Cocoa

- (MyView *)myView { 
    if (myView != nil) 
     return myView; 

    myView = [[UIView alloc] initWithFrame:CGRectZero]; // allocate memory if necessary. 
    // further init here 

    return myView; 
} 

- (void)discardView { 
    [myView discard]; // the discard methods puts the view offscreen. 
    [myView release]; // free memory! 
} 

- (void)showView { 
    view = [self myView]; 
    // more code that puts the view onscreen. 
} 

Malheureusement, cette méthode ne fonctionne que la première fois. Les demandes suivantes pour mettre la vue à l'écran entraînent des erreurs "message sent to deallocated instance". Apparemment, une instance désallouée n'est pas la même chose que rien. J'ai pensé à mettre une ligne supplémentaire après [myView release] qui lit myView = nil. Cependant, cela pourrait entraîner des erreurs (tout appel à myView après cette ligne donnerait probablement des erreurs).

Alors, comment puis-je résoudre ce problème?

+0

Si vous faites des appels à myView après l'avoir publié, vous * voulez * que les erreurs soient générées. – walkytalky

Répondre

4

Le réglage myView à nil est la bonne chose à faire ici. Non ce faisant, c'est ce qui génère des erreurs, car il se réfère indétectablement à un objet désalloué. Votre code teste nil pour voir s'il doit créer une nouvelle vue, vous devez donc définir la variable de manière appropriée.

1

Vous allez avoir des problèmes parce que vous n'utilisez pas d'accesseurs. Vous devez définir une propriété pour la vue. Ensuite, à chaque fois que vous vous référez à la vue, utilisez la notation par points. Si vous faites cela, il vous suffit de définir la propriété view sur zéro comme ceci:

self.myView=nil; 

... déclenchera sa libération automatiquement.

Cependant, ceci est une mauvaise façon de gérer la vue, surtout si vous la chargez depuis la plume. La vue est probablement une propriété obligatoire d'un objet contrôleur. Le réglage à zéro invite les plantages.

La meilleure solution consiste à demander au contrôleur de vue de gérer les problèmes de mémoire. Sur l'iPhone, vous pouvez mettre le code de gestion de la mémoire dans viewDidDisappear: ou didReceiveMemoryWarning. Dans tous les cas, vous ne tirez pas sur la vue tant que le contrôleur est actif mais libérez plutôt les parties de la vue qui consomment beaucoup de mémoire. images. Cela laisse la vue en tant qu'objet shell léger. Puis, dans 'viewWillAppear`, vous chargez à nouveau les pièces consommant beaucoup de mémoire.

Cependant, la meilleure façon de gérer ce problème consiste à ouvrir le contrôleur de vue à partir d'une pile de navigation. À ce stade, le contrôleur de vue nettoie automatiquement après lui-même.