2010-02-06 4 views
1

Compte tenu de l'extrait de code suivant:Objective-C: init objet et gestion de la mémoire

...

- (void) setTotalAmount: (NSNumber*)input 
{ 
    [totalAmount autorelease]; 
    totalAmount = [input retain]; 
} 

- (void) dealloc 
{ 
    [totalAmount release]; 
    [super dealloc]; 
} 

...

Ce que je veux vraiment comprendre comment nous avons mis en valeur. Nous allouons local (instance) var et "retain" à l'entrée var. Mais qu'est-ce que "input"? Est-ce un indicateur de la valeur réelle? Ou est-ce la valeur elle-même? Lorsque nous "conservons", est-ce que nous obtenons un pointeur sur "input" ou un pointeur vers une valeur ou juste la valeur?

Et même questions avec dealloc et version. Qu'est-ce qui "meurt" ici?

Merci!

+0

Je pense que vous voulez dire 'Nous autorelease local (instance) var et "conserver" l'entrée var.' Pas "allouer"; il n'y a aucune allocation qui se passe dans votre extrait de code. – erikprice

Répondre

3

Il est clair que input est un pointeur. Vous avez déclaré son type dans la liste d'arguments en tant que NSNumber*.

input est un pointeur vers un objet de type NSNumber. En interne, l'objet possède une variable entière qui contient le nombre de références externes. Envoyer le message retain à un objet augmentera son nombre de références. L'envoi du message release diminuera le nombre. L'envoi du message ajoutera l'objet au pool d'autorelease local qui gardera trace des objets auto-libérés et leur enverra le message release la prochaine fois qu'il sera drainé. Un objet avec le nombre de références de 1 qui reçoit un message release sera désalloué et sa méthode dealloc sera appelée. Vous devriez libérer toutes les ressources que vous détenez lorsque vous êtes libéré. Lorsque vous définissez une propriété, vous voulez libérer l'ancienne valeur et vous assurer que la nouvelle valeur est conservée tant que l'objet lui-même est actif. Pour vous assurer que la nouvelle valeur est conservée, vous augmentez le nombre de références de 1 en lui envoyant le message retain. Pour libérer l'ancien objet, vous lui enverrez le message de libération. Il y a un problème subtil ici. Si l'ancienne valeur est la même que la nouvelle valeur, si vous libérez l'ancienne valeur en premier et que son nombre de retenues est de 1, il sera détruit avant que vous puissiez l'incrémenter. C'est pourquoi vous devriez conserver la nouvelle valeur avant de libérer l'ancien.

-1
entrée

est le NSNumber

- (void) setTotalAmount: (NSNumber*)**input** 

qui est appelé en faisant quelque chose comme ceci:

[object setTotalAmount:number]; 
+0

Non, 'input' est un pointeur vers l'instance NSNumber.La distinction est importante pour cette question. Et votre exemple ne compilera pas - vous montrerez que 'setTotalAmount' est appelé avec un argument int, mais le paramètre de cette méthode est tapé comme un pointeur vers NSNumber. – erikprice

+0

oh merde, je fais toujours ça! –

1

En supposant que vous avez instancié un objet de la classe ci-dessus nommé « myObject », vous pouvez définir son totalAmount comme ceci:

...

// get a new NSNumber object which will be autoreleased 
NSNumber *amount = [NSNumber numberWithInteger:10]; 

// call the setter which will autorelease the previous value of 
// totalAmount (if any), retain the object referenced by "amount" 
// (so that object will no longer be deallocated when it's autoreleased), 
// and reference that object from the totalAmount instance variable 
myObject.totalAmount = amount; 

...

Plus tard, quand « myObject » est désallouée, l'objet référencé par la variable d'instance totalAmount sera libéré (et désallouée si elle n'a pas été retenu nulle part ailleurs).