Reputation: 26223
Can anyone tell me if the NSString instance variable "planetName" needs to be allocated / released by me (as in the example below) or is that done when the class instance is created / allocated?
My understanding is that int and float don't need to be, but not sure about NSString & NSArray ...
@interface PlanetClass : NSObject {
NSString *planetName;
}
- (NSString *)planetName;
- (void)setPlanetName:(NSString *)value;
@end
Like this ...
- (id) init {
[super init];
planetName = [[NSString alloc] init];
return self;
}
- (void) dealloc {
[planetName release];
[super dealloc];
}
** ---------------------------------- ** EDIT: EDIT: Here is another version ** ---------------------------------- **
int main(int argc, const char *argv[]) {
// ** Allocated here
PlanetClass *newPlanet_01 = [[PlanetClass alloc] init];
NSString *newPlanetName = [NSString alloc] init];
// ** Set the instance variable pointer here
newPlanetName = @"Jupiter";
[newPlanet_01 setPlanetName:newPlanetName];
// ** Released here
[newPlanet_01 release];
return 0;
}
the init & dealloc methods would then be like this ...
- (id) init {
[super init];
return self;
}
- (void) dealloc {
// Always release the current copy of planetName
// pointed to by the class instance.
[planetName release]
[super dealloc];
}
The setPlanetName method would look like this ...
- (void)setPlanetName:(NSString *)newPlanetName {
if (planetName != newPlanetName) {
[planetName release];
planetName = [newPlanetName copy];
}
}
PS: I am not using properties or synthesize, I have not gotten that far yet.
cheers -gary-
Upvotes: 3
Views: 1524
Reputation: 31280
Your code is valid, but there's probably no reason to initialize planetName to an empty string. One of the nice features of Objective-C is that you can send messages to a nil object with no consequence. If your class is initialized and you never call -setPlanetName:
, planetName will be nil (instance variables are always initialized to nil
), so when your -dealloc
method calls [planetName release]
, nothing will happen.
In general, the best practice is to use -copy
when setting an NSString instance variable, and -retain
when setting most other objects as instance variables. As such, your -setPlanetName:
method would look something like this:
- (void)setPlanetName:(NSString *)newPlanetName {
NSString *tempPlanetName = [newPlanetName copy];
[planetName release];
planetName = tempPlanetName;
}
Upvotes: 3
Reputation: 95335
You still have an issue with your new code.
In your main function, you release newPlanetName
but this is a little wrong. Your PlanetClass
retained it with its setPlanetName:
method, but your PlanetClass
never releases it again unless the name of the planet changes. It should not be up to the caller of setPlanetName:
to keep hold of the string, it is your classes responsibility to deal with it appropriately.
Your old dealloc
method is correct. It should release the planet's name because your PlanetClass
no longer needs it. Your main method should not release the planet's name because the string returned by stringWithString:
does not belong to you, and you give it to PlanetClass
to take care of.
So, keep your old dealloc
method, and remove the [newPlanetName release]
from the main function and you should be alright from there.
As a shortcut, you can even call [newPlanet_01 setPlanetName:@"Jupiter"]
and do away with the newPlanetName
variable altogether in your main function.
Upvotes: 1
Reputation: 25619
planetName is a pointer which, like an int or float, does not need to be allocated or initialized.
Just like you can assign values to an int or float, you can point planetName at different instances of a string, or it can point at nothing.
When you init your class, planetName will be nil (not pointing at anything). If you point planetName to an instance of a string, you have to retain that string, and release in dealloc.
In other words, this:
planetName = [[NSString alloc] init];
is unnecessary and meaningless.
In your setPlanetName method you would need to release the existing string that planetName is pointing to, assign planetName to the new string, and then retain the new string.
Your dealloc method is correct.
Upvotes: 1
Reputation: 35925
Your code looks good. NSObject
subclasses (NSString
included) need to have their memory mananged by the object that owns them. In this case, that owner is PlanetClass
.
Upvotes: 0