views:

72

answers:

3

I have this userInputstring in the header that will be modified and used by multiple methods in the .m file

.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
    }

but I kept getting memory leak problems. What's the proper way to set it up? Im new to objective c.

A: 

Try to use autorelease pool:

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

    ....
    // Your code here

    [pool drain]
    return 0;
}
Sumai
A: 

@"blablabl" is a shorthand to create an autoreleased NSString from a constant string. If if you don't have an autorelease pool in the thread you are running, those NSString object won't ever be released and of course your create a leak.

Either create an autorelease pool as Sumai suggest or release those objet's memory yourself. (tip: create an NSAutorelesePool ;-) )

VdesmedT
Constant NSStrings e.g. @"foo" are never released even with an autorelease pool.
JeremyP
+2  A: 

I don't know where or how to release

Right, you first need to familiarise yourself with the Cocoa Memory Management Rules.

In summary, if you obtain an object by alloc, a method containing "copy", a method starting with "new" or if you retain it, you need to release or autorelease.

Take method1:

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

userInputString was not obtained with alloc, new or copy, nor have you retained it. Therefore you do not own it so you must not release it. If you had done this:

userInputString = [@"foo" copy];

or this:

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

or this:

userInputString = [@"foo" retain];

you do own the string therefore you must release or autorelease it.

When you release it depends on its scope. If it's a local variable, you must release or autorelease it before the block it is declared in exits. If it is an instance variable, you must release it before the object it is in is deallocated. i.e. you must release it in the dealloc method for the object. In all cases, if you overwrite an object you own, you must release it first. So:

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

This is one of the reasons for adding getters and setters for instance variables. Every time you set a new value, you have to release the old value and retain the new value (making sure that the old bvalue and new value are different), so this is encapsulated in the setter. A synthesized property adds this code automatically.

JeremyP
@JeremyP thanks for your detailed answer. I'm still confused about the last code exmaple and the last paragraph in your answer. So if I make userInputString a property. @property (nonatomic, copy) NSString *userInputString in the .h file, what do I need to do each time I set it to the value of a local string in a method? Is it just userInputString = [someOtherString copy]? and the property releases the value currently stored and takes the new value?
Fasid
@Fasid: It you write `userInputString =`, you aren't using the property accessor, you're just setting the instance variable. It would have to be `self.userInputString =` or `[self setUserInputString:` for the property to be relevant.
Chuck
@chuck I see. what about for memory management? Is what I said correct? I only need to release the property one in dealloc?
Fasid
@Fasid: That's right. A `retain` property will handle its own memory management, and you just need to release the object in `dealloc`.
Chuck
what about copy? @property (nonatomic, copy) NSString
Fasid
Copy properties handle their own memory management too. You would only need to do `[self setUserInputString: someString]` or `self.userInputString = someString`. You still need to release the ivar in dealloc though.
JeremyP
also you said use self.userInputString to set the property value. what if i want to get the value? do i do localString = self.userInputString? or just localString = userInputString
Fasid
`localString = self.userInputString` or `localString = [self userInputString]`. The former is just syntactic sugar for the latter.
JeremyP
thanks ........
Fasid