Allocating memory for NSString?
cocoa, memory, objective-c
Solution
Read the memory management rules. 9 simple paragraphs that explain everything you need to know.
Because geekName does not begins with “alloc” or “new” or contains “copy”, it should be returning a string you do not “own”. As such, you do not need to (and indeed, must not) release it, and you also must not store a reference to it. You may return it from the method you are in, in which case your method name also should not begins with “alloc” or “new” or contains “copy”.
If you wish to keep it around, you must take ownership of it by calling retain, or because its an NSString, better is copy. This might be automatic if you assign it to a copy/retain property.
In the code you have now posted, you have made an error in your setter. Your setter should be taking a copy of the input parameter, something like:
- (void)setGeekName:(NSString*)gName {
if ( geekName != gName ) {
[geekName release];
geekName = [gName copy];
}
You then also need a dealloc routines which releases geekName:
- (void) dealloc
{
[geekName release];
[super dealloc];
}
Alternatively, you can use Objective C properties. Instead of your interface showing:
- (NSString*) geekName;
- (void) setGeekName:(NSString*)gName;
Use a property:
@property (nonatomic, copy) NSString* geekName;
And instead of your implementation of the setters and getters, let the system synthesize them for you:
@synthesize geekName;
You still need the dealloc method to free geekName.
Problem
I am new to Objective-C and I am a little curious about how I should be managing the memory for the local NSString variables shown below and the associated instance variables inside the class object. The code I have works fine, but just curious as to best practice. Edited to include full code, nothing special, like I say I am just curious if in this context I should be doing alloc/release on the NSString objects. ``` // MAIN ------------------------------------------------------------------- ** #import <Foundation/Foundation.h> #import "PlanetClass.h"; int main (int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *planet_01_Geek; NSString *planet_02_Geek; // Create planets PlanetClass *newPlanet_01 = [[PlanetClass alloc] init]; [newPlanet_01 setGeekName:@"StarWars"]; PlanetClass *newPlanet_02 = [[PlanetClass alloc] init]; [newPlanet_02 setGeekName:@"Dune"]; // Query a planet planet_01_Geek = [newPlanet_01 geekName]; planet_02_Geek = [newPlanet_02 geekName]; // Print details NSLog(@"Planet Geek = %@", planet_01_Geek); NSLog(@"Planet Geek = %@", planet_02_Geek); // Clean up [newPlanet_01 release]; [newPlanet_02 release]; [pool drain]; return 0; } ``` .. ``` // CLASS HEADER ----------------------------------------------------------- ** #import <Foundation/Foundation.h> @interface PlanetClass : NSObject { NSString *geekName; } - (NSString*) geekName; - (void) setGeekName:(NSString*)gName; @end // ------------------------------------------------------------------------ ** ``` .. ``` // CLASS BODY ------------------------------------------------------------- ** #import "PlanetClass.h" @implementation PlanetClass - (NSString*)geekName { return geekName; } - (void)setGeekName:(NSString*)gName { geekName = gName; } @end // ------------------------------------------------------------------------ ** ```