Gestion de la mémoire - Doute

Didier Guillion

Membre expert
Club iGen
20 Juillet 2001
3 244
164
62
Toulouse
www.myriad-online.com
Bonjour,

J'ai écrit une fonction Objective C qui substitue une chaine de caractere par une autre chaine.

La voici :
/***************************************************************************
SubstituteString
****************************************************************************/
- (NSString *) SubstituteString:(NSString *)source fromTable:(NSString *)tag fromTable:(NSString *)substWith
{
NSArray *listItems;

listItems=[source componentsSeparatedByString:tag];
if(listItems)
source=[listItems componentsJoinedByString:substWith];
return(source);
}

La question que je me pose est si je dois libérer l'objet listItems avant de rendre la main.

Dans la doc Cocoa j'ai lu qu'il n'était pas nécessaire de liberer les objets implicitiment alloués.

Est ce le cas ici ?

Cordialement
 
Moi j'dirais qu'il n'y a pas besoin...

Tu peux éventuellement mettre
listItems = [NSArray array];
pour être sûr qu'elle est autorelease...

Mets, es-tu sûr que ta fonction est bien utile? ;-)
Il existe replaceOccurrencesOfString:withString:eek:ptions:range: qui semble faire le même boulot, voir doc ObjC Foundation, au rayon NSMutableString.

Sinon, j'ai une petite méthode qui évite de faire appel à componentsSeparatedByString et componentsJoinedByString parce qu'elles sont "relativement" lentes... Sur un gros nombre de remplacement ou de gros texte, ça se ressent.

<font class="small">Code:</font><hr /><pre>- (NSString *)replaceTheString:(NSString *)targetString intoString:(NSString *)textContents byString:(NSString *)replaceString
{

NSAutoreleasePool *otherpool = [[NSAutoreleasePool alloc] init];
NSMutableString *temp = [[NSMutableString alloc] init];
NSRange replaceRange = NSMakeRange(0, [textContents length]);
NSRange rangeInOriginalString = replaceRange;
int replaced = 0;
while (1)
{
NSRange rangeToCopy;
NSRange foundRange = [textContents rangeOfString:targetString options:0 range:rangeInOriginalString];
if (foundRange.length == 0) break;
rangeToCopy = NSMakeRange(rangeInOriginalString.location,foundRange.location - rangeInOriginalString.location);
[temp appendString:[textContents substringWithRange:rangeToCopy]];
[temp appendString:replaceString];
rangeInOriginalString.length -= NSMaxRange(foundRange) -rangeInOriginalString.location;
rangeInOriginalString.location = NSMaxRange(foundRange);
replaced++;
if (replaced % 100 == 0)
{
[otherpool release];
otherpool = [[NSAutoreleasePool alloc] init];
}
}
if (rangeInOriginalString.length &gt; 0) [temp appendString:[textContents substringWithRange:rangeInOriginalString]];
[otherpool release];
return [temp autorelease];
}</pre><hr />

 
Bonjour,

Et merci de ta réponse. J'avais en effet survolé replaceOccurrencesOfString mais je l'avais ignoré (a tord apparemment) pour deux raisons :

- Elle ne marche pas sur Mac OS inférieur a X.2
- Je ne comprends pas encore tres bien la notion de "mutable" mais cela viendra, je pense...

En fait, je suis en train de pallier des déficiences d'AppleScript sur des systemes Japonais qui ne produit pas le meme resultat sur les chaines de caracteres.

Je ne suis pas sur qu'AppleScript gere les "mutables" ? Qu'en penses tu ?

Merci infiniment pour ton aide, je découvre Obj-C, et je progresse lentement...

Cordialement
 
Didier, la règle dans cocoa c'est : tu alloues un ojet avec les methodes alloc, allocWithZone ou tu fais une copie d'un objet avec les methodes copy, copyWithZone, etc, tu DOIS liberer cet objet par la methode release.
Autrement tu ne t'en préoccupe pas.

De même tu veux utilisé un objet que t'as pas créé, tu dois avant tout le 'retenir' par [trucmuch retain] avant de l'utiliser, puis le libérer une fois terminé par [trucmuch release]

Enfin pour renvoyer un objet alloué par tes soins tu le ranges dans l'autorelease pool par [trucmuch autorelease] qui se chargera de le libérer.

Etant donné que chaque Application a un autorelease pool par défaut, l'appli avant de se terminer envoie un release à son autorelease pool. Celui-ci envoie à tous les objets qu'il contient un release pour les liberer avant de se libérer lui-même.

En définitive, dans une méthode, tout alloc d'un objet est suivi soit par le release de l'objet soit par son autorelease.
Dans ton cas c'est une déclaration qui implicitement met ton objet dans l'autorelease pool par défaut de l'appli.
Tu dois déclarer un objet 'nutable' si tu modifies son aspect.
Ainsi si tu veux avoir un array extensible (dans lequel tu peux ajouter et soustraire des éléments), il faut le déclarer NSMutableArray et non un NSArray.

J'espère avoir été assez clair.