2009-05-03 5 views
3

J'apprends encore la gestion de la mémoire Objective-C. J'essaye d'implémenter plusieurs classes simples dans un exemple de programme que je construis.Objectif-C 2,0; Attribuer une propriété; Fuite de mémoire?

À titre d'exemple, disons que je la définition de classe suivante:

#import <UIKit/UIKit.h> 

@interface customViewController : UIViewController 
{ 
    customObject *myCustomObject; 
} 

@property (retain) customObject *myCustomObject; 

- (void)replaceCustomObject:(customObject *)newObject; 

@end 

Pour la propriété, j'utiliser le mot-clé standard synthétisent ...

@synthesize myCustomObject; 

Alors s'il vous plaît supposer que dans l'instance de customViewController myCustomObject est déjà défini avec une valeur valide et est en cours d'utilisation. Ensuite, la méthode replaceCustomObject est définie comme:

- (void)replaceCustomObject:(customObject *)newObject 
{ 
    //Does this cause a memory leak because I just assign over 
    //the existing property? 
    self.myCustomObject = newObject; 
} 

Comme le commentaire demande, cette mémoire-t fuite? Ou est-ce la manière valide de remplacer un objet précédent par un nouvel objet?

Merci,
Frank

Répondre

2

C'est parfaitement valable et ne fuit pas la mémoire. Les accesseurs synthétisés gèrent correctement les comptes de conservation. En aparté, vous n'avez pas besoin de cette méthode replaceCustomObject: puisque votre propriété est readwrite par défaut, vous avez une méthode setCustomObject auto-générée que les clients de votre classe peuvent utiliser, et qui suit la normale Cocoa conventions de nommage)

+0

Je sais que je n'ai pas besoin de la méthode replaceCustomObject:. C'était juste un moyen pour moi d'illustrer mon objectif global. Comme vous pouvez l'imaginer, j'utilise beaucoup plus que l'attribution d'une propriété.:-) Merci de répondre à ma question. –

1

la syntaxe accesseur propriété

self.x = y; 

a le même effet que d'appeler la méthode setter explicitement:.

[self setX:y]; 

La méthode accesseur fera tout ce qui a été écrit pour faire. Dans votre cas, pour une propriété @property (retain) qui a été @synthesized, l'accesseur va libérer l'ancien objet et conserver le nouveau. Donc, en appelant le setter, que ce soit explicitement ou par le biais de '.' syntaxe, fera la bonne chose - y compris la bonne gestion de la mémoire.

Donc, en bref: non, cela ne fuira pas la mémoire.

2

Selon this, si vous utilisez (conserviez) dans votre déclaration, la méthode de synthèse libérera l'ancienne valeur, puis retenir la nouvelle:

if (property != newValue) { 
    [property release]; 
    property = [newValue retain]; 
} 
3

Comme d'autres l'ont mentionné, votre code est parfaitement valide et ne fuira pas la mémoire lors de l'affectation à la propriété.

Si vous avez oublié d'implémenter une méthode correcte dealloc, le dernier objet affecté sera divulgué lorsque votre customViewController est détruit. Une implémentation correcte de dealloc ressemblerait à ceci:

- (void)dealloc 
{ 
    self.myCustomObject = nil; 
    [super dealloc]; 
} 
+0

Pouvez-vous expliquer plus loin? Je n'ai jamais vu mettre une propriété à zéro. Est-ce égal à faire [self.myCustomObject release]? C'est ainsi que j'ai appris à m'en occuper dans la méthode dealloc ... –

+0

L'envoi de [self.myCustomObject release] est dangereux car, après cela, self.myCustomObject pointe toujours vers l'objet maintenant libéré! Dans la méthode dealloc, il est probablement sûr puisque self est détruit de toute façon, mais je n'aime pas avoir des règles spéciales à retenir. Pour être sûr, vous pouvez également faire ce qui suit: [myCustomObject release]; myCustomObject = nil; – rpetrich