2

Je suis une fuite de mémoire sur ce point:De retour des objets avec autorelease mais je fuir encore la mémoire

ma classe personnalisée:

+ (id)vectorWithX:(float)dimx Y:(float)dimy{ 
return [[[Vector alloc] initVectorWithX:dimx Y:dimy] autorelease]; } 


- (Vector*)add:(Vector*)q { 
return [[[Vector vectorWithX:x+q.x Y:y+q.y] retain] autorelease]; } 

déléguer app je le lancer:

Vector *v1 = [[Vector alloc] initVector]; 
Vector *v2 = [[Vector alloc] initVector];  
Vector *vtotal = [[v1 add:v2] retain]; 

[v1 release]; 
[v2 release]; 
[vtotal release]; 

Comment cette des fuites? Je les libère ou les autoelease correctement. L'application se bloque immédiatement si je ne les conserve pas, à cause d'une libération anticipée je suppose. Il se bloque également si j'ajoute une autre version.

+0

Vous n Il ne faut pas conserver/autoelease le nouveau vecteur dans add, il suffit de retourner le résultat de [Vector vectorWithX: Y:]. Pouvez-vous poster le code pour initVector et tel? –

+0

merci beaucoup pour la réponse, j'ai déjà supprimé retenir/autorelease d'ajouter, mais fuit toujours. le vecteur init est ceci: (x et y sont synthétisés) - (id) initVector {self = [super init]; si (auto-) {x = 0; y = 0; } retournez-vous; } – gok

Répondre

2

Pourquoi pensez-vous que vous fuyez la mémoire? Commence avec ça. Et quel objet plantez-vous en accédant? Cela vous indiquera très probablement quel est l'objet de votre sous-conservation. Si je devais faire une supposition, je soupçonnerais initVector, juste parce que c'est un nom très étrange pour une méthode. Qu'est ce que ça fait? Pourquoi n'est-il pas appelé simplement "init"?

Est-ce que ce code est enfilé? Vous faites beaucoup plus de conservation/autorelease que ce qui est généralement approprié. Vous n'avez pas besoin de conserver un objet pour le conserver dans la boucle d'événement en cours. D'une manière générale, vous ne retenez que des ivars, car ceux-ci sont ce dont vous avez besoin dans la prochaine boucle d'événements. Si vous avez beaucoup d'appels à conserver en dehors des accesseurs, alors vous êtes presque certainement en train de gérer la mémoire. Ci-dessus doivent être:

+ (id)vectorWithX:(float)dimx y:(float)dimy 
{ 
    return [[[Vector alloc] initVectorWithX:dimx y:dimy] autorelease]; 
} 

- (Vector*)add:(Vector*)q 
{ 
    return [Vector vectorWithX:(self.x + q.x) y:(self.y + q.y)]; 
} 

... 

Vector *v1 = [[Vector alloc] initVector]; 
Vector *v2 = [[Vector alloc] initVector]; 
Vector *vtotal = [v1 add:v2]; 
... 
[v1 release]; 
[v2 release]; 

Personnellement, je gérer v1/v2 avec autorelease parce que je pense que cela rend le code plus maintenable et compréhensible, mais il y a d'autres écoles de pensée:

Vector *v1 = [[[Vector alloc] initVector] autorelease]; 
Vector *v2 = [[[Vector alloc] initVector] autorelease]; 
Vector *vtotal = [v1 add:v2]; 
+1

Hey @Rob, vous avez sur-relâché vos vecteurs dans votre exemple de nettoyage (autorelease après l'initialisation puis relâchez spécifiquement à la fin). –

+0

Je les ai tous les deux en arrière ... Merci. Fixé. –

+0

@gok, En regardant votre code dans le commentaire ci-dessus, la méthode en question devrait être juste "init" pas "initVector". Et vous devriez vous assurer que vous utilisez des accesseurs plutôt que d'accéder directement à vos ivars. Ne pas utiliser d'accesseurs est la cause n ° 1 des erreurs de mémoire comme ce que vous voyez. Oui, je sais que ce sont des flotteurs. Utilisez les accesseurs de toute façon. Probablement votre fuite réelle est ailleurs; probablement dans quelque chose d'autre qui retient le vecteur. (Mais pourquoi pensez-vous avoir une fuite, btw?) –

Questions connexes