2009-12-29 5 views
2

J'ai ce problème concret, mais si vous trouvez ma conception initiale idée folle et une meilleure suggestion, s'il vous plaît laissez-moi savoir :)Problème de libération objet à l'aide « removeFromSuperView » iPhone

J'ai un UIView qui agit comme conteneur/arrière-plan pour ajouter d'autres vues. L'important est qu'une seule vue soit présente à la fois. Donc, avant de faire tout en ajoutant des points de vue que je fais ceci:

 for(UIView *v in [self.currentView subviews]) { 

     [v removeFromSuperview]; 
    } 

self.currentView est la vue que j'ajouter mes sous-vues à.

Après cela, j'ajouter une nouvelle UIView de cette manière:

 UIView *tempView; 

    switch (self.currentIndex) { 
     case 1: 
      tempView = [[AView alloc] initWithFrame:frame]; 
      [self.currentView addSubview:tempView]; 
      [tempView release]; 
      break; 
     case 2: 
      tempView = [[AView alloc] initWithFrame:frame]; 
      [self.currentView addSubview:tempView]; 
      [tempView release]; 
      break; 
     default: 
      break; 
    } 

De cette façon, je supprimer tous les points de vue, depuis que je relâche le droit tempView après que je l'ajoute à la self.currentView je me retrouve avec un Conserver le compte d'un sur le UIView vivant actuellement dans currentView. Tout cela semble bien, mais quand je le regarde avec des Instruments, je peux voir que chaque fois que je lance le code ci-dessus, un nouvel objet AView est alloué et l'ancien continue de traîner avec un nombre de retenue de 1, soit I Il me manque une action de rétention évidente en cours d'exécution sur mon objet ou bien le "removeFromSuperView" n'appelle pas "release" sur ma vue.

Dans la vraie vie, mes objets ne sont pas de type AView, mais de plusieurs types différents, mais de cette façon je peux tester s'il y a toujours une seule instance AView allouée. Comme je peux le lire dans la documentation "removeFromSuperView" devrait appeler "release" sur la vue, donc je suis un peu confus quant à savoir pourquoi mes vues ne sont pas libérées.

Encore une fois, peut-être que je vais à ce sujet dans le mauvais sens et les suggestions sont les bienvenues. La configuration est qu'il y a un certain nombre de bouton en bas de l'écran et lorsque l'utilisateur clique sur la vue change.

Merci pour toute aide ou pointeurs donné :)

+0

Si une seule vue est présente à la fois, pourquoi utilisez-vous une boucle pour supprimer la vue? –

+0

Qu'est-ce que c'est pour ... en syntaxe? Je pensais que l'objectif-c ne supportait pas ... dans. – martinr

+0

Salut et merci les gars. La boucle for consistait principalement à tester par point d'arrêt le nombre de vues supprimées, elle ne s'exécute qu'une seule fois. Je peux voir que je change la collection en l'énumérant et que cela pourrait poser problème. Mais cela fera-t-il une différence? Le code de suppression est exécuté pour la vue unique qui vit là ... Le for..in devrait être bien :) il a travaillé jusqu'à présent. S'agit-il de la boucle qui conserve une référence à l'objet? Merci encore – RickiG

Répondre

2

Vous itérez une collection et changer en même temps il

Essayez

while ([self.currentView subviews].count>0) { 

    [[[self.currentView subviews] objectAtIndex:0] removeFromSuperView]; 
} 

à la place.

+0

Ce fut à grande bouche pleine de cacao: \t \t while ([self.currentView subviews] .count> 0) { \t \t \t \t \t \t UIView * v = [[self.currentView subviews] objectAtIndex: 0]; \t \t \t [v removeFromSuperview]; \t \t} a mieux fonctionné. Mais le nombre d'AViews allouées augmente tout de même. J'ai commencé Instruments/Object Allocation. coché le "Créé et vivant encore" et puis j'ai couru ce code en continu, ce qui pourrait être faux? – RickiG

+0

Vous voulez sûrement auditer la liste de conservation/diffusion à l'aide d'Instruments et regarder les piles pour voir quels objets verrouillent vos AViews? J'ai l'impression que Cmd + E est utile pour faire apparaître cette information dans Instruments. Si vous n'avez pas encore utilisé cette fonctionnalité, essayez de créer des sous-classes de test NSObject triviales pour comparer la liste de traces d'audit pour une version complète et une version échouée [retain> 0]? Qu'est-ce que tu vois, Ricki? – martinr

+0

J'ai mis à jour mon Xcode à la version 3.2.1 et maintenant il semble que les sous-vues soient vraiment publiées en utilisant removeFromSuperView. Peut-être qu'il n'y avait "pas de cuillère" et que les Instruments ne l'ont tout simplement pas compris. J'ai également fait fonctionner l'analyseur statique et je suppose qu'il ramasserait sur un problème potentiel de ce genre tout de suite. Mais il est revenu propre, donc je suis confiant qu'il n'y a pas de fuite. Merci encore pour votre contribution :) – RickiG

0

vous pouvez essayer les fonctions "bringSubviewToFront" et "sendSubviewToBack" au lieu de créer un nouveau UIView à chaque fois. De cette façon, vous ne créerez pas d'uiviews pour chaque action et vous serez donc moins pressant sur la consommation de mémoire de votre application.

+0

Salut learner11, merci pour l'entrée. J'ai un scrollView avec des pages X, chacune de ces pages peut contenir Y des vues ci-dessus. Cela signifie que si j'ai 10 pages et 6 de la vue ci-dessus (pages dans la direction X des vues dans la direction "Z"). L'utilisateur peut potentiellement avoir 60 vues en mémoire à la fois. C'est la principale raison pour laquelle je souhaite m'assurer que je nettoie complètement tout. De cette façon, un utilisateur peut charger jusqu'à 10 x 1 vues et les faire défiler sans effectuer de chargement. Ceci est bien dans la mémoire que je suis prêt à attacher ici. – RickiG