2010-09-17 4 views
0

Bonjour à tous, je suis encore jeune dans le développement de l'iPhone, mais j'ai une grande expérience avec d'autres langages de programmation. La chose qui me fait arracher les cheveux est la gestion memmory Obj-C et relâcher/retenir correctement. Je connais le concept, je sais "une fois que je comprend que ce sera facile" mais je ne suis pas encore tout à fait là, et ça me rend fou. Ici j'ai un simple morceau de code avec la classe et la méthode, qui ajoute simplement un caractère à la chaîne existante qui est synthétisée ainsi utilisée comme classe proprety ... la classe par exemple s'appelle myClass ...libérer et conserver NSString * correctement

myClas.h

@interface myClass : NSObject { 
    @private 
    NSString* someCommonString; 
} 
@propery (retain, nonatomic) NSString* someCommonString; 

myClass.m

... 

@synthesize someCommonString;  

- (id) init 
{ 
    self = [super init]; 

    if(self) 
    { 
     someCommonString = [[NSString alloc] initWith String:@"one "]; 
    } 
} 

- (NSString*) appendString:(NSString*) stringToAdd 
{ 
    NSString* result = [someCommonString stringByAppendingString: stringToAdd]; 
    return result; 
} 

- (void) doTheJob 
{ 
    NSString* test1 = @"two "; 
    NSString* test2 = [[NSString alloc] initWithString: @"three "]; 
    NSString* test3 = [NSString stringWithFormat:@"four "]; 

    self.someCommonString = [self appendString:test1]; 
    self.someCommonString = [self appendString:test2]; 
    self.someCommonString = [self appendString:test3]; 

    NSLog(@"%@", someCommonString); 
} 

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

Ok, après que j'alloc myClass et exécuter la méthode doTheJob, je devrais avoir @ "un deux trois quatre" dans le proprety de classe someCommonString. Je sais que ça marche, mais ça fuit aussi. test1, test2 et test3 sont 3 façons d'initialiser NSString, et seulement test2 devrait être libéré, c'est assez explicite, mais beaucoup plus inquiet de ce qui se passe en les passant comme arguments à la méthode appendString. Parce que je sais que j'ai une fuite, mais je ne sais pas comment gérer l'argument 1. stringToAdd [devrais-je m'inquiéter à ce sujet dans la méthode appendString du tout?] 2. le résultat -> si j'autelease le résultat, je ne sais pas savoir à quel moment le résultat sera désaffecté. 3. sommeCommonString dans appendStringMethod, dois-je le conserver, le libérer ou le laisser seul?

Huh :)

Répondre

1

À première vue, il me semble que vous n'êtes pas libérer test2. Après l'avoir ajouté à votre chaîne commune, vous n'avez plus besoin de la conserver.

self.someCommonString = [self appendString:test1]; 
self.someCommonString = [self appendString:test2]; 
self.someCommonString = [self appendString:test3]; 
[test2 release]; 

Les deux autres (test1 et test3) sont autoreleased, de sorte que votre thread les récupérer à un moment donné).

En ce qui concerne votre méthode appendString: concerne, result est déjà autoreleased et en fait, vous pourriez réduire votre mise en œuvre à

return [someCommonString stringByAppendingString: stringToAdd]; 

someCommonString est pas affectée par l'opération du tout. stringByAppendingString: renvoie une nouvelle chaîne auto-libérée à partir de la concaténation de self et stringToAdd.

espoir qui aide

+0

Merci beaucoup! Bien que cette stringByAppendingString n'ait pas été libérée – cybercow

0

... mais im beaucoup plus inquiet ce qui se passe quand les faisant passer comme arguments à la méthode appendString. Parce que là, je sais que je HAWE une fuite, mais je ne sais pas comment gérer
1. arguments StringToAdd [devrais-je inquiéter à ce sujet dans la méthode appendString du tout?] ...

Vous ne disposez pas d'une fuite au -appendString:. Vous passez stringToAdd autour sans le retenir et c'est correct ici. Le result est auto-libéré et vous n'avez aucune action à effectuer.

2.  le résultat -> si j'autelease le résultat, je ne sais pas à quel point le résultat sera libéré.

Le résultat est déjà publié et sera publié dès que le NSAutoreleasePool actuel sera publié. Donc, vous pouvez le transmettre sans le retenir.

3.   SommeCommonString dans appendStringMethod, devrais-je le conserver, le relâcher ou le laisser seul?

Laissez-le seul, il est géré par les accesseurs. Mais en tant que fedmest (et vous aussi) a déclaré: libérer test2.

0

Bien qu'il y ait quelques problèmes dans votre code, mais le problème de base est que vous avez besoin de la chaîne NSMutableString, pas de NSString pour que votre code fonctionne.

  1. dans la méthode init, code correct pour initialiser est,

    someCommonString = [[NSMutableString alloc] initWithString:@"one "];

  2. Vous devez retourner l'objet (auto) à partir init, sinon il ne fonctionnera pas, comme celui-ci.

    return self;

  3. Si vous vouliez ajouter la chaîne, il devrait être NSMutableString, pas NSString.

    [[self someCommonString] appendString:test1];

    [[self someCommonString] appendString:test2];

    [[self someCommonString] appendString:test3];

  4. Dans la méthode dealloc, vous appelez dealloc méthode de super, pas super libérer. Alors corrigez-le comme ça.

    [super dealloc];

  5. Il n'y a pas besoin de libérer test1 et test3, parce qu'ils sont autorelease.

J'ai le code correct, essayez-le.

@interface myClass : NSObject { 
@private 
    NSMutableString* someCommonString; 
} 
@property (retain, nonatomic) NSMutableString* someCommonString; 

- (void) doTheJob; 
@end 


@implementation myClass 
@synthesize someCommonString; 


- (id) init 
{ 
    self = [super init]; 

    if(self) 
    { 
     someCommonString = [[NSMutableString alloc] initWithString:@"one "]; 
    } 

    return self; 
} 

- (NSString*) appendString:(NSString*) stringToAdd 
{ 
    NSString* result = [someCommonString stringByAppendingString: stringToAdd]; 
    return result; 
} 

- (void) doTheJob 
{ 
    NSString* test1 = @"two "; 
    NSString* test2 = [[NSString alloc] initWithString: @"three "]; 
    NSString* test3 = [NSString stringWithFormat:@"four "]; 

    [[self someCommonString] appendString:test1]; 
    [[self someCommonString] appendString:test2]; 
    [[self someCommonString] appendString:test3]; 



    NSLog(@"%@", someCommonString); 

    [test2 release]; 
} 

- (void) dealloc 
{ 
    [someCommonString release]; 
    [super dealloc]; 
} 
@end 
+0

Merci beaucoup pour vos efforts. Désolé, j'ai fait quelques fautes de frappe, et j'ai oublié de retaper le retour ... Un peu inquiet pour votre redou, avec [[self someCommonString] appendString ... vous appelez une méthode appendAstring sur someCommonString qui génère un sélecteur reconnu. 4 moi cela ne fonctionnerait que s'il est utilisé avec des catégories avec NSString/NSMutableString? J'ai utilisé stringByAppendingString sur Nulltring regullar sans problème, mais je ne sais pas si c'est correct? – cybercow

+0

stringByAppendingString ne concaténera que la chaîne avec votre objet chaîne et retournera la chaîne ajoutée, mais cela ne changera pas le contenu de votre chaîne d'origine. – itsaboutcode

0

Ceci est une technique qui pourrait vous aider à mieux gérer ce qui se passe avec la directive @synthesize. Changer votre tête comme suit

@interface myClass : NSObject { 
    @private 
    NSString* _bob; 
} 
@property (retain, nonatomic) NSString* someCommonString; 

et votre fichier de classe à

@synthesize someCommonString = _bob; 

Si vous recompiler votre code, vous obtiendrez des erreurs de compilation. Corrigez-les et vous serez soudainement en mesure de voir exactement à quoi vous accédez via la propriété synthétisée et à quoi vous accédez directement.

En outre, comme déjà mentionné, vous devez libérer test2 dans la méthode doTheJob.

+0

Vous avez également attrapé mon doute qui était caché entre les lignes! Je vais essayer ça, merci beaucoup! – cybercow

Questions connexes