What is leaking in this statement using replaceObjectAtIndex - iphone

Instruments tells me the following line from the code below is leaking: I can't figure out how to fix this leak.
[self.selectedElement.usrAdvancedBuyingPercents replaceObjectAtIndex:selectedRow withObject:[numberFormatter stringFromNumber:percentage]];
- (IBAction) simpleMarginSliderValueChanged:(UISlider *)sender {
NSDecimalNumber *percentage = (NSDecimalNumber *)[NSDecimalNumber numberWithFloat:[sender value]];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setPositiveFormat:#"#.##"];
[self.selectedElement.usrAdvancedBuyingPercents replaceObjectAtIndex:selectedRow withObject:[numberFormatter stringFromNumber:percentage]];
[numberFormatter release];
}

The NSString you are creating from the number is not being released somewhere.
The problem is not in the code that is shown - it's somewhere else that is taking a string from that array, retaining it, then not releasing it. Leaks just shows you where memory that is leaked was initially allocated, and the only thing on that line that is allocating memory is [numberFormatter stringFromNumber:percentage].
Either that, or the whole array is not being released correctly (but then whatever builds usrAdvancedBuyingPercents would also show that is leaking).

Related

MutableCopy AllocLeak MemoryLeak

I have an NSTimer that fires once per second.
And every second I have an NSString that needs to be changed.
I've never tried to deal with memory management before so I'm not sure if what I'm doing is right but instruments is saying under "alloc" that the line of code with stringByReplacingOccurrencesOfString has 45MB of "Live Bytes" after about a minute...
(and the live byte count keeps on rising with every second and eventually crashes the app).
I think my issue lies somewhere with the MutableCopy code?
Here is my code:
-(void)myTimer {
if (testedit) {
[testedit release];
[withString1a release];
[forString1a release];
}
testedit = [[NSString alloc] init];
withString1a = [[NSString alloc] init];
forString1a = [[NSString alloc] init];
testedit = [[NSString alloc] initWithFormat:#"example"];
withString1a = [[NSString alloc] initWithFormat:#"e"];//this string gets its values randomly from an array in my real code
forString1a = [[NSString alloc] initWithFormat:#"flk34j"];//this string gets its values randomly from an array in my real code
testedit = [[testedit stringByReplacingOccurrencesOfString:withString1a withString:forString1a] mutableCopy];//memory leak /:
}
You are allocating memory for each object twice. When you alloc the second time and assign it to the same variable, the first piece of alloc'd memory becomes inaccessible and unreleasable.
Then you make a mutableCopy of testedit and assign the copy to the original's variable. Again, you leave a piece of inaccessible memory floating around.
The rule with non-ARC memory management is - for every alloc, new, copy or retain you need to have a corresponding release. You have 6 allocs, one copy, and only 3 releases.
Here are some suggestions.
Remove these duplicated allocations:
testedit = [[NSString alloc] init];
withString1a = [[NSString alloc] init];
forString1a = [[NSString alloc] init];
Presumably testedit, withString1a and forString1a are all iVars. (Please declare your iVars as autosynthesized properties and refer to them as self.testedit ... etc. that will make your code so much clearer to stack overflowers).
Take out all of this:
if (testedit) {
[testedit release];
[withString1a release];
[forString1a release];
}
Assuming these are all iVars, the correct place to release them is in your object's dealloc method
In fact withString1a and forString1a can be local variables, as you get their content from elsewhere:
NSString* withString1a = [[[NSString alloc] initWithFormat:#"e"] autorelease];
NSString* forString1a = [[[NSString alloc] initWithFormat:#"flk34j"] autorelease];
You can autorelease them as you don't need them to hang around after the method has finished.
These lines can also be written:
NSString* withString1a = [NSString stringWithFormat:#"e"];
NSString* forString1a = [NSString stringWithFormat:#"flk34j"];
(-stringWithFormat is a convenience method that returns an autoreleased object)
That leaves us with these two lines.
testedit = [[NSString alloc] initWithFormat:#"example"];
testedit = [[testedit stringByReplacingOccurrencesOfString:withString1a
withString:forString1a] mutableCopy];
It's not clear why you are treating testedit as an immutable string in the first line and a mutable string in the second. You don't need a mutable string here at all, as you are replacing testedit with a new string.
self.testedit = [[NSString alloc] initWithFormat:#"example"];
self.testedit = [[testedit stringByReplacingOccurrencesOfString:withString1a
withString:forString1a] copy];
(you need copy as stringByReplacingOccurrencesOfString:withString: returns an autoreleased object, and here you want to keep hold of it)
THE last piece of the jigsaw is getting rid of your _testedit iVar memory allocation. You do this in the dealloc method of your object:
- (void) dealloc {
[_testEdit release];
[super dealloc];
}
(Note that init, accessor, and dealloc methods are the three places where you should not refer to an iVar using property syntax.)
All good, but really, you should be using ARC! You are _far_more likely to introduce memory bugs this way than if you rely on the compiler to manage memory for you.
I would suggest you to make use of #property here.
In .h file declare the properties as:
#property (nonatomic, retain) NSString *testedit;
#property (nonatomic, retain) NSString *withString1a;
#property (nonatomic, retain) NSString *forString1a; //if required write the #synthesize as well in .m class
You can write your timer method as:
-(void)myTimer {
self.testedit = #"example";
self.withString1a = #"e";//this string gets its values randomly from an array in my real code
self.forString1a = #"flk34j";//this string gets its values randomly from an array in my real code
self.testedit = [self.testedit stringByReplacingOccurrencesOfString:self.withString1a withString:self.forString1a];
}
In dealloc method, you can set all the above properties as nil (self.testedit = nil;) or do a release on them([testedit release];).
If possible, try to switch to ARC, you dont have to worry about the memory management. The problem with your code was that you are using a lot of alloc/init statements without releasing the variable before doing it. This causes it to lose the reference of that variable and you will leak it. You dont need that many allocation statements. For every allocation or retain, there should be a corresponding release/auto-release statement.
If you're using ARC you shouldn't have an issue. If you aren't using ARC you can try adding autorelease:
testedit = [[[testedit stringByReplacingOccurrencesOfString:withString1a withString:forString1a] mutableCopy] autorelease];
You are getting a memory leak because you never de-allocate testedit. Whenever you call alloc, that means you need to deallocate it. This usually just means calling release.
Do something like this instead, then be sure to free up the memory you've allocated:
NSString* newString = [[testedit stringByReplacingOccurrencesOfString:withString1a withString:forString1a] mutableCopy];

Why does this line leak memory?

[row setObject:[NSString stringWithCString:value encoding:NSUTF8StringEncoding] forKey:columnName];
where row is a NSMutableDictionary..is there a different way to inject this string into my dictionary?
Profiling tools says that because the string is "autoreleased", so you could optimize it by
putting a NSAutoreleasePool around it
alloc/init the str then release it
or just ignore the optimization message.
This is one way:
NSString *str = [[NSString alloc] initWithCString:value encoding:NSUTF8StringEncoding];
[row setObject:str forKey:columnName];
[str release];
I have had this problem before, because the NSMutableDictionary owns the object it won't be released until the Dictionary is released.
I would suggest that somewhere in your code an object is being dealloc'd without properly releasing the variables it owns, likely the NSMutableDictionary *row.

Memory leak of an NSMutableArray using Instruments

According to the leak instrument in XCode it's saying this line is giving a memory leak (100%)?
self.unsentPatients = [[NSMutableArray alloc] initWithArray:[defaults arrayForKey:UNSENT]];
I'm correctly releasing etc. on dealloc (which is definitely being ran) so I don't understand where I am going wrong?
It's only a small leak and Analysis doesn't come up with anything, but nonetheless it's still a leak.
Kind regards,
Dominic
There are many things wring with this code.
I'm assuming that the property is retaining the value, then you should not assign the value the way you are doing now, but more like:
NSMutableArray *temp = [[NSMutableArray alloc] initWithArray:[defaults arrayForKey:UNSENT]];
self.unsentPatients = temp;
[temp release], temp = nil;
or
self.unsentPatients = [[[NSMutableArray alloc] initWithArray:[defaults arrayForKey:UNSENT]] autorelease];
You should also avoid using the self. syntax in dealloc or init, which will call a mutator.
In multithreaded environment this could give problems.
So the correct dealloc would be:
- (void) dealloc {
[unsentPatients release], unsentPatients = nil;
[super dealloc][;
}

NSNumberFormatter leaks on NSCFNumber getObjectValue

I created a common method "isValidAmount" to check if the user inputs a correct amount in UITextField. This is working, but the problem is, I am getting leaks when the number is invalid. The leaked object is "NSCFNumber" and the responsible for that is "getObjectValue". I don't know what else to do. I already release the "formatter" below. I even tried to release "number" below. But still I keep on getting this leak. Please help.
+ (BOOL) isValidAmount:(NSString *)amount {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *number = [formatter numberFromString:amount];
[formatter release];
if (!number) {
return NO;
}
return YES;
}
By inspection, there is nothing wrong with that code.
Does it also leak on the device? Can you post the exact backtrace of the allocation that is leaked?

Why Instruments report a leak?

I am developing an iphone app. Instruments reported a leaked object ServiceTypes. Below is the relevant code. Does anyone have any ideas? Thanks a lot for your help.
ServiceTypes *serviceTypes = [[ServiceTypes alloc] init];
if ([userConnection getServiceTypes:serviceTypes]) {
if ([serviceTypes.types length] > 0) {
NSArray *array = [[NSArray alloc] initWithArray:[serviceTypes.types componentsSeparatedByString: SERVICE_TYPE_DELIMITOR]];
serviceRequestTypes = [[NSMutableArray alloc] initWithArray:array];
[array release];
}
}
[[self typesTableView] reloadData];
[serviceTypes release];
It doesn't look like serviceTypes is being leaked. From the code you posted, serviceTypes is always released at the end of the method, and it doesn't appear to be retained anywhere in your sample. My question is: what happens inside getServiceTypes:. Does that method retain the serviceTypes parameter?
One more thing. If serviceRequestTypes is an instance variable (and it looks like it is), then you may be leaking memory by reassigning it without releasing the existing serviceRequestTypes object first. You should either rewrite serviceRequestTypes to be a property and use a synthesized accessor or make sure to release it every time before assigning. If its current value is nil, no big deal; the release message will simply be ignored. For example:
[serviceRequestTypes release];
serviceRequestTypes = [[NSMutableArray alloc] initWithArray:[serviceTypes.types componentsSeparatedByString:SERVICE_TYPE_DELIMITER]];