2010-09-08 6 views
0

Je cette userInputstring dans l'en-tête qui sera modifié et utilisé par plusieurs méthodes dans le fichier .mproblème simple avec NSString

.h 
NSString *userInputString; 
    -(void)main; 
    -(void)method1; 
    -(void)method2; 

.m 
    -(void)main{ 
    [self method1]; 
    [self method2]; 

    } 


    -(void)method1{ 
    NSString *localString = @"something"; 
    userInputString = localString; 
    //do something else with it 
    } 


    -(void)method2{ 
    NSString *localString = [NSString stringWithFormat:@"%@ insert something",userInputString]; 
    userInputString = localString; 
    [someOtherMethod:userInputString];//Crash 
    } 

mais je gardais avoir des problèmes de fuite de mémoire. Quelle est la bonne façon de le configurer? Im nouveau à l'objectif c.

+0

pouvez-vous envoyer le journal des erreurs –

+0

aucun message d'erreur, juste fuite de mémoire. trouvé en utilisant des instruments. – Fasid

+1

Vous devez montrer comment vous CRÉEZ la chaîne et comment vous la libérez si vous le faites. Sinon, nous ne pouvons pas savoir ce qui ne va pas – willcodejavaforfood

Répondre

2

Je ne sais pas où ni comment libérer

droit, vous devez d'abord vous familiariser avec le Cocoa Memory Management Rules. En résumé, si vous obtenez un objet par alloc, une méthode contenant "copy", une méthode commençant par "new" ou si vous la conservez, vous devez libérer ou libérer.

Prenez method1:

-(void)method1{ 
    userInputString = @"something"; 
    } 

userInputString n'a pas été obtenue avec alloc, nouvelle ou copie, ni vous avez conservé ce. Par conséquent, vous ne le possédez pas, vous ne devez donc pas le libérer. Si vous aviez fait cela:

userInputString = [@"foo" copy]; 

ou ceci:

userInputString = [[NSString alloc] initWithString: @"foo"]; 

ou ceci:

userInputString = [@"foo" retain]; 

vous possédez la chaîne que vous devez donc libérer ou AutoRelease il.

Lorsque vous le relâchez, cela dépend de sa portée. S'il s'agit d'une variable locale, vous devez la libérer ou la libérer avant que le bloc déclaré ne soit fermé. S'il s'agit d'une variable d'instance, vous devez la libérer avant que l'objet dans lequel elle se trouve soit désalloué. c'est-à-dire que vous devez le libérer dans la méthode dealloc pour l'objet. Dans tous les cas, si vous remplacez un objet que vous possédez, vous devez le libérer en premier. Donc:

userInputString = [someOtherString copy]; // you own userInputString 

// do some stuff 

[userInputString release];     // you no longer own it 
userInputString = [someOtherString retain];// overwrite the pointeer with something else 

C'est l'une des raisons de l'ajout de getters et setters pour les variables d'instance. Chaque fois que vous définissez une nouvelle valeur, vous devez libérer l'ancienne valeur et conserver la nouvelle valeur (en vous assurant que l'ancienne valeur et la nouvelle valeur sont différentes), de sorte que ceci est encapsulé dans le setter. Une propriété synthétisée ajoute ce code automatiquement.

+0

@JeremyP merci pour votre réponse détaillée. Je suis toujours confus au sujet du dernier code exmaple et du dernier paragraphe de votre réponse. Donc, si je mets une propriété userInputString. @property (nonatomic, copy) NSString * userInputString dans le fichier .h, que dois-je faire chaque fois que je le mets à la valeur d'une chaîne locale dans une méthode? Est-ce juste userInputString = [someOtherString copy]? et la propriété libère la valeur actuellement stockée et prend la nouvelle valeur? – Fasid

+1

@Fasid: Si vous écrivez 'userInputString =', vous n'utilisez pas l'accesseur de propriété, vous définissez simplement la variable d'instance. Il devrait être 'self.userInputString =' ou '[self setUserInputString:' pour que la propriété soit pertinente. – Chuck

+0

@chuck je vois. Qu'en est-il de la gestion de la mémoire? Est-ce que ce que j'ai dit est correct? J'ai seulement besoin de libérer la propriété en dealloc? – Fasid

0

Essayez d'utiliser la piscine autorelease:

int main() 
{ 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 

    .... 
    // Your code here 

    [pool drain] 
    return 0; 
} 
0

@ "blablabl" est un raccourci pour créer un autoreleased NSString à partir d'une chaîne constante. Si vous ne disposez pas d'un pool d'autorelease dans le thread que vous exécutez, ces objets NSString ne seront jamais libérés et, bien sûr, vous créerez une fuite. Créez un pool autorelease lorsque Sumai suggère ou libère vous-même la mémoire de cet objet. (Astuce: créer une NSAutorelesePool ;-))

+1

NSStrings constants par ex. @ "foo" ne sont jamais libérés même avec un pool autorelease. – JeremyP