views:

48

answers:

3

Alright, this is an elementary question but I'm asking because I honestly don't understand how to properly manage this. If I uncomment the last two lines, this code crashes, even though I don't think it should.

The following code is from a custom subclassed UILabel where I added the following method, setTextFromFloat.

 -(void)setTextFromFloat:(float)newValue {  
 NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];  
 [formatter setMaximumFractionDigits:2];  
 [formatter setRoundingMode:NSNumberFormatterRoundUp];  

 NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:newValue]];  
 NSString *newLabelValue = [numberString stringByAppendingString:@"x"];  
 self.text = newLabelValue;  
 //[numberString release];  
 //[formatter release];  
}

So, there are three object here that I am confused about:

a) self.text (the old string value) - When is this released? Should I release the old contents of self.text when I call this function?

b) formatter, the NSNumberFormatter I alloc'd here almost certainly needs release

c) what about numberString? I just use it as an intermediary to build newLabelValue. if I release it I believe the program crashes, but why? Am I not responsible for the memory used indirectly by calling stringFromNumber?

Any wisdom greatly appreciated, thank you!

A: 

numberString must not be released. You are getting it through a convenience constructor, so it's auto-released.

About your self.text property, if you haven't declared it, you're not responsible. Otherwise, it needs to be released in the dealloc method.

Macmade
A: 

Release only the formatter at the end of your setTextFromFloat: method.

Because your class inherits from UILabel, self.text is a part of the UILabel class and will be released in UILabel's dealloc method, so you don't have to release it yourself if in your subclass's dealloc method you call [super dealloc].

numberString is being created using NSString.stringFromNumber: so it's already set to autorelease from within the internal method. Don't manually release it, or your program will crash.

BoltClock
+1  A: 

So, there are three object here that I am confused about:

a) self.text (the old string value) - When is this released? Should I release the old contents of self.text when I call this function?

self.text is not an object, it is a property, which means it is the pair of accessors -text and -setText: If it has an instance variable backing it and it has retain or copy semantics, you must release the instance variable in -dealloc.

b) formatter, the NSNumberFormatter I alloc'd here almost certainly needs release

Not "almost certainly" but "certainly".

c) what about numberString? I just use it as an intermediary to build newLabelValue. if I release it I believe the program crashes, but why? Am I not responsible for the memory used indirectly by calling stringFromNumber?

Review the Cocoa Memory Management rules. Did you obtain numberString by new, alloc or a method containing copy? No you didn't. Did you retain it? No you didn't. Therefore, you must not release it because you do not own it. If you want to own it, send -retain to it. Then you must release it when you no longer need to keep it around.

JeremyP