2011-10-19 2 views
0

J'ai vu quelques articles sur ce sujet ici sur SO, mais pas de réponses définitives. Voici mon problème.UINavigationController: Libérer la mémoire de ViewController quand elle est apparue

J'ai un UINavigationController que j'utilise comme galerie. Sur le premier contrôleur, je charge un tas d'images distantes. Cela augmente ma taille de la mémoire, mais pas autant. En cliquant sur une image, il va pousser sur un autre viewController qui a des images pour la galerie juste cliqué. Cela peut charger dans un autre 1 Mo ou plus de données à partir de ces images.

Le problème ici est qu'un utilisateur peut parcourir n'importe quel nombre de ces galeries. Depuis que j'ouvre le viewController, cette mémoire n'est pas libérée, je commence à utiliser trop de mémoire dans mon application lorsque les utilisateurs continuent à parcourir les galeries.

Y at-il un moyen que je peux libérer cette mémoire lorsque j'appelle viewController? Peut-être dans ma méthode viewDidDisappear:? Si oui, que libérerais-je? Et comment puis-je le créer à nouveau? J'ai essayé cela jusqu'à un certain point, comme libérer mon point de vue, mais j'ai des plantages.

Avez-vous un aperçu de ce problème?

PhotosGalleryiPad *gallery = [[PhotosGalleryiPad alloc] init]; 
gallery.items = self.items; 
gallery.asset = self.currentAsset; 
[self.navigationController pushViewController:gallery animated:YES]; 
[gallery release]; 
+0

Honnêtement ... il semble que la mémoire doit vraiment être décharger dans "dealloc" de la vue que vous avez chargé lorsque vous l'avez retiré de la pile. Etes-vous sûr que vous publiez toutes les données de la photo dans dealloc correctement? À moins que vous n'autorisiez l'utilisateur à naviguer dans un tas de vues à l'infini sans jamais cliquer sur le bouton «Précédent» ... les vues dans le navigateur de vue devraient se décharger sur un clic du bouton précédent dans l'en-tête en général. Si tel est le cas, vous voudrez peut-être regarder un paradigme de navigation différent. – Delete

+0

Non, dealloc est appelé et mes propriétés sont publiées. Ils cliquent simplement, poussent le contrôleur, puis cliquent sur le bouton "retour" normal pour revenir à la racine. –

Répondre

0

Si vous « popping » vues sur le premier plan comme celui-ci:

infoScreen = [[[infoScreen alloc] initWithNibName:@"InfoScreen" bundle:nil] autorelease]; 
infoScreen.view.center = CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2); 
[self.view sendSubviewToBack:self.view]; 

Alors vous feriez [infoScreen release]; pour libérer/libérer la vue de la mémoire.
Rappelez-vous tout ce que vous alloc, ou retain (il existe d'autres situations aussi, mais je les oublie en main), vous devez release.

+0

Je comprends les règles de gestion de la mémoire. Je ne suis pas sûr de suivre votre suggestion ici. –

+0

Peut-être que j'ai mal compris votre question, je pensais que vous aviez besoin d'aide pour libérer la mémoire des viewcontrollers qui ne sont plus utilisés. –

+0

Je le fais, il semble que cela tient sur la mémoire lorsque j'éteins le contrôleur de vue de la pile. –

0

Normalement, vous libérez de la mémoire dans la méthode dealloc du contrôleur de vue qui est retiré de la pile.

Toutefois, si vous parlez d'images et que vous les avez chargées avec [UIImage imageNamed:], UIKit peut les mettre en cache. Essayez de simuler un avertissement de mémoire dans le simulateur (dans le menu Matériel) et voyez si cela décharge ces images mises en cache.

Vous pouvez également effectuer une analyse de type heapshot dans Instruments. Marquez le tas avant de charger le contrôleur de vue, marquez-le à nouveau après avoir fermé le contrôleur de vue, et voyez quels objets restent collés.

0

Où exactement conservez-vous ces images? Laissez-moi supposer que gallery.items est une collection mutable (éventuellement un tableau) contenant les images. Lorsque l'utilisateur visite de nouvelles galeries, d'autres images sont ajoutées à ce tableau. De contrôleur de vue pour afficher le contrôleur, vous passez un pointeur vers ce tableau:

gallery.items = self.items; 

Ainsi, lorsque vous pop le contrôleur de vue, vous êtes toujours à gauche avec la même agrandie, un tableau. Le problème, alors, est de savoir comment éliminer ce tableau des images nouvellement ajoutées lorsque vous ouvrez un contrôleur de vue.

Plutôt que de passer un pointeur, vous pouvez créer un shallow copy of the collection. Si c'est un tableau modifiable, vous pouvez le faire comme suit:

gallery.items = [self.items mutableCopyWithZone:nil]; 

Ensuite, lorsqu'un contrôleur de vue est relevé, sa gamme items est libéré.Les objets ajoutés par le contrôleur de vue éclatée sont libérés, mais les anciens objets sont toujours conservés dans le tableau items du contrôleur de vue précédent.

(je prends juste une supposition. Si je me trompe, il serait utile que vous nous avez expliqué où vous conserver ces images.)

+0

Non, ce n'est pas un tableau d'images. C'est un tableau d'URL d'images, juste NSStrings. J'ai besoin de faire des recherches, j'ai le sentiment que cela pourrait être causé par un code tiers que j'utilise. –

+0

Cela ne semble pas être le contrôleur de vue qui retient les images. Si vous libérez des propriétés de manière appropriée dans le dealloc, la seule façon dont je peux penser qu'un contrôleur de vue conserve quelque chose est à travers une collection qui n'est pas copiée. Peut-être que si vous regardez où les images sont créées ou téléchargées, vous trouverez ce qui les retient. –

+0

Merci, fera l'affaire. –

Questions connexes