2010-04-17 3 views
0

J'ai UINavigationController contrôlant plusieurs vues. L'une des vues est composée de 20 pages déroulantes. Chaque page est construite à la volée à partir de UIViews en ajoutant des boutons, des étiquettes, des UIImageViews, etc. Lorsque cette UIView est retirée de la pile, l'utilisation de la mémoire reste la même. Par conséquent, il continue à augmenter si je continue à pousser/éclater cette vue.L'utilisation de la mémoire ne diminue pas - aucune fuite si

Dans mon dealloc, je suis en train de parcourir les 20 pages et de trouver chaque type d'objet qui a été ajouté via addSubview et de faire une release mais les instruments disent que mon utilisation de la mémoire ne baisse jamais! J'essaie d'utiliser 'retainCount' pour voir ce qui se passe avec les objets que je libère mais je ne reçois peut-être pas d'image réelle via retainCount. Pour certains éléments, retainCount montre 2 alors j'essaie de relâcher cet objet deux fois mais ensuite l'application plante. Si je le libère une fois qu'il fonctionne, mais l'utilisation de la mémoire ne descend jamais :(

Q1: Ai-je besoin de parcourir chaque élément puis de publier un élément sur cet élément? Pourquoi ne puis-je pas libérer un objet parent et tous les objets? contenue par elle obtiendrait libérés automatiquement

Q2: Est-retainCount un indicateur fiable

+0

Débogué plus loin. Voici ce que j'ai trouvé jusqu'ici. J'ai un UIScrollView sur lequel j'ajoute 20 objets UIViews. Même 20 UIViews sont ajoutés à NSMutableArray. Les instruments me montrent que lorsque la vue est affichée, chacun des 20 UIView reste en place.D'accord, je pense que je dois avoir oublié de le 'libérer' de quelque part, alors il faut que le compte soit fini. J'ai trouvé en effet qu'il y avait un endroit. Donc juste après la ligne [self.scrollView addObject: page]; // page étant un UIView J'ai ajouté [libération de page]; Mais maintenant, après avoir libéré NSMutableArray lorsque je publie les accidents de l'application self.scrollView. – climbon

+0

Après NSZombieEnabled et je vois cette erreur *** - [Communiqué CFString]: message envoyé à l'instance désallouées 0x3ea6f00 Trouvé NSStackLoggingNoCompact = 1 contribuerait à voir en quelque sorte la variable associée à l'adresse dans l'accident en utilisant « informations 0x3ea6f00 malloc-histoire ' Après cela, je vois une trace de la pile qui pointe vers une ligne dans ma vue de destination où j'alloue un NSMutableArray. Je passe ce tableau à la vue étant sauté. Je pensais que je devais juste "retenir" le tableau qui se passait, mais cela n'a pas aidé. App continuer à se bloquer et pointer sur la même ligne. Je n'ai jamais été bloqué si mal :( – climbon

Répondre

1

Résolu le problème. Voici des morceaux de casse-tête qui m'ont dérouté pendant toute la semaine dernière. 20 Les objets UIView ont tous deux été référencés par un UIScrollView et un tableau NSMutableArray. Les libérer de l'un ne les libérait pas complètement puisqu'ils étaient encore référencés par l'autre. Après avoir été ajoutés à UIScrollView, j'appelle la libération sur chaque UIView afin que le nombre de retenue reste 1.

Chacun de ces 20 UIViews utilisait en interne un tableau qui lui était passé depuis la vue précédente - via un simple pointeur. Après avoir utilisé des objets à l'intérieur du tableau transmis, je les libérais aussi. Ainsi, après la fixation de la conserver le nombre ci-dessus quand je suis finalement arrivé à libérer toute la vue (par popping retour à la vue précédente) l'application a commencé écraser avec des messages comme * - [Communiqué CFString]: message envoyé à l'instance désallouées 0x3ea6f00

Tracing les via NSStackLoggingNoCompact = 1 On m'avait dit qu'il y avait un problème autour du tableau que je passais à la vue que j'avais poussée plus tôt sur la pile et que je venais de ressurgir. Mais je ne pouvais pas retracer où. J'ai essayé d'augmenter la retenue sur l'ensemble du tableau mais cela n'a pas aidé puisque je n'étais pas en train de conserver sur les objets à l'intérieur du tableau. Quoi qu'il en soit, finalement trouvé le code incriminé où je libérais des objets d'un tableau transmis. Je l'ai changé pour copier le contenu du tableau et maintenant l'application ne plante pas et toutes les vues sont libérées. Phew!

0

Etes-vous sûr que vous êtes à la recherche octets net Si vous êtes à la recherche par hasard à octets d'ensemble, qui ne sera jamais en bas?. Le nombre net d'octets est le nombre actuel d'octets alloués par votre application

Lorsque vous libérez un pa louer un objet, il devra libérer tout ce qu'il possède en dealloc :. Si vous relâchez la vue principale, cette vue libère toutes ses sous-vues si elle est désallouée.

En outre, retainCount n'est généralement pas un indicateur fiable. Poursuivre les dénombrements peut être une tâche décourageante en raison de la nature sous-jacente d'UIKit et de la Fondation. De nombreuses classes d'Apple retiendront et relâcheront des objets, et vous n'aurez aucun moyen de savoir où et quand cela se produit.

+0

En effet en regardant net octets.J'effectue la libération juste après avoir appuyé sur la vue sur le contrôleur de navigation.Lorsque le bouton de retour est pressé, je le fais \t [self.navigationController popToViewController: [[self.navigationController viewControllers] objectAtIndex: [expéditeur selectedSegmentIndex]] animé: OUI]; \t pourrait-il être le popToViewController est en quelque sorte ne libère pas la vue actuelle – climbon

+0

popToViewController retourne un tableau des contrôleurs qui ont été affichaient Essayez une boucle à travers ce tableau et libérer?. – rickharrison

+0

@rickharrison: faire cela est une très bonne/mauvaise idée de faire la gestion de la mémoire correctement: c = [[UIController alloc] init ...]; [navController pushViewContro ller: c aanimé: OUI]; [c libération]; <- relâcher juste après avoir poussé – rpetrich