2010-03-12 4 views
1

Question stupide, mais pourquoi avons-nous besoin d'utiliser «retenir» lors de la déclaration d'une propriété? Ne sera-t-il pas conservé quand on lui aura assigné quelque chose?objectif-c 2.0 propriétés et «conserver»

En regardant cet exemple, il semble qu'un objet est automatiquement conservé quand alloué, alors quel est le point?

#import "Fraction.h" 
#import <stdio.h> 

int main(int argc, const char *argv[]) { 
    Fraction *frac1 = [[Fraction alloc] init]; 
    Fraction *frac2 = [[Fraction alloc] init]; 

    // print current counts 
    printf("Fraction 1 retain count: %i\n", [frac1 retainCount]); 
    printf("Fraction 2 retain count: %i\n", [frac2 retainCount]); 

    // increment them 
    [frac1 retain]; // 2 
    [frac1 retain]; // 3 
    [frac2 retain]; // 2 

    // print current counts 
    printf("Fraction 1 retain count: %i\n", [frac1 retainCount]); 
    printf("Fraction 2 retain count: %i\n", [frac2 retainCount]); 

    // decrement 
    [frac1 release]; // 2 
    [frac2 release]; // 1 

    // print current counts 
    printf("Fraction 1 retain count: %i\n", [frac1 retainCount]); 
    printf("Fraction 2 retain count: %i\n", [frac2 retainCount]); 

    // release them until they dealloc themselves 
    [frac1 release]; // 1 
    [frac1 release]; // 0 
    [frac2 release]; // 0 

■ sortie

Fraction 1 conserve count: 1

Fraction 2 retenir count: 1

Fraction 1 conserve count: 3

Fraction 2 conserve count: 2

Fraction 1 retenir nombre: 2

Fraction 2 retenir le nombre: 1

fraction Deallocing

fraction Deallocing


Ce me rend fou!

Répondre

3

Le comportement par défaut d'une propriété est ASSIGN et non RETAIN. Ce ne sont pas les mêmes comportements. Si votre propriété est pour un type de données primitif, tel qu'un int, alors ASSIGN serait correct à utiliser. Cependant, si vous spécifiez (retenez) et que la propriété pointe vers un pointeur d'objet tel qu'un objet NSObject *, le pointeur reçoit l'adresse de mémoire de l'objet et son compte de retenue est incrémenté de un. Si votre programme ne consiste en rien d'autre qu'une seule fonction principale, son but est difficile à voir. Cependant, supposons que votre classe a cette méthode:

-(void)setMyArrayWithString:(NSString *)s{ 
    myArray = [NSArray arrayWithObject:s]; 
    } 

monTableau Suppose est défini comme NSArray * monTableau et a la déclaration @property appropriée (conserver). Tout fonctionne correctement jusqu'à ce que la méthode retourne. C'est parce que l'objet renvoyé par NSArray est un objet autoreleased. Si nous ne le conservons pas, il sera libéré par NSAutoReleasePool et nous ne pourrons pas l'utiliser (et nous aurons des bogues désagréables et de mauvaises violations d'accès). Pour corriger cela, nous pouvons faire une des deux choses:

-(void)setMyArrayWithString:(NSString *)s{ 
    self.myArray = [NSArray arrayWithObject:s]; 
// OR 
    myArray = [[NSArray arrayWithObject:s] retain];  
} 

La première solution utilise self.myArray d'utiliser la définition @property. Ce code affecte puis conserve l'objet afin que nous ne le perdions pas lorsque la fonction revient. La deuxième solution définit le pointeur NSArray * myArray manuellement, puis conserve manuellement l'objet NSArray. Dans tous les cas, NSAutoreleasePool libère l'objet à la fin de la fonction, mais il ne sera pas libéré, car il nous reste à le conserver.

+0

donc un objet autoreleased créé dans une méthode est libéré lorsque la méthode revient? Je ne savais pas que ... je pensais que tu devais l 'autorelease et ensuite ça traînait jusqu'à ce que tu libères la piscine? – Adam

+0

@Adam Cela dépend du NSAutoreleasePool dans lequel l'objet a été placé. Si vous créez une application non-Cocoa dans laquelle vous créez explicitement le NSAutoreleasePool, la disponibilité du pool dépend de vous. Cependant, si vous utilisez un framework Cocoa tel que AppKit ou UIKit, lorsque vous créez des objets autorelease, ils sont placés dans un pool géré par Cocoa. De temps en temps, pendant le run-loop, le cacao draine la piscine.Donc, si vous utilisez un pool que vous ne gérez pas, comme le cacao, conservez les objets qui doivent survivre après le retour d'une méthode. –

+0

Ok, c'est logique - merci! – Adam

Questions connexes