Memory Leak: Issues with releasing NSArray in iPhone app
I have a code which shows leaks in Instruments. It shows leaks where I initialize the arrayDetPerformance
with the contents of arrayDetail
If I release my arrayDetail
then my app crashes.
What could be wrong?
Here is the code:
NSDictionary *finalResult = [extractUsers JSONValue];
// NSLog(@" Stamp-16 : %@",[NSDate date]);
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 2
// NSLog(@"Data is : %@",array1);
// NSLog(@" Stamp-17 : %@",[NSDate date]);
//NSLog(@"Final Value is : %@",[[allUsers objectAtIndex:0] valueForKey:@"password"]);
//[self setUserData:allUsers];
//[tblView reloadData];
[responseString release];
[request release];
}
//sleep(0.3);
//[inProgressIndicator stopAnimating];
[fileContents release];
//Release all the allocated data
[json release];
//label.text = @"Finish";
// NSLog(@" Stamp-19 : %@",[NSDate dat开发者_C百科e]);
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
//NSLog(@"Array2 : %d",[array2 retainCount]);
arrayDetPerformance = [[NSMutableArray alloc] initWithArray:arrayDetail];
chartPoints= [arrayDetPerformance valueForKey:@"Points"];
NSLog(@"Chart Points: %@",chartPoints);
[def setObject:chartPoints forKey:@"yarray"];
[def setObject:@"YES" forKey:@"flagThumb"];
//array1 = [[NSMutableArray alloc] initWithObjects:@"New",@"Table",@"View",nil];
//[self.Dettable reloadData];
//sNSFileManager *fileManager = [NSFileManager defaultManager];
//[array2 release];
NSLog(@"ArrayDEtPerfomance : %d",[arrayDetPerformance retainCount]);
NSLog(@"array2 : %d",[arrayDetail retainCount]);
if([chartPoints count]>0)
{
PlotItem *plotItem = [[PlotGallery sharedPlotGallery] objectAtIndex:0];
[plotItem imageHive:Fund];
}
//[arrayDetail release];
}
Memory leak is shown on the line
arrayDetPerformance = [[NSMutableArray alloc] initWithArray:arrayDetail];
Also I am confused on why the retain count directly goes from 0 to 2 in the below code:
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 2
What could be wrong?
It shows a leak because you allocate arrayDetPerformance
and then not release it. Simple as that. At least that's what we can tell from the code you are showing us.
As for the rest, don't use retainCount
to debug memory problems, ever! You have to understand the simple memory management rules and follow them, nothing else. Since you don't know what Apple's underlying code does, you cannot rely on the retain count of an object.
As to your question relating to this code:
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 2
You are assigning a whole other object to arrayDetail
so it's completely meaningless to compare any properties of arrayDetail
before and after the assignment. The retain count could be all over the place and it would not tell you anything.
I get the impression that you don't really know what you are doing here. You should read the memory management rules again and again until you understand them thoroughly.
retainCount
won't help you debug your problem (in fact it will almost never be relevant to debugging, so best forget it's even there).
Don't release arrayDetail
, as you don't own it. The problem is with arrayDetPerformance
. You're allocing an object on that line, and it's not being released anywhere. Now, you may be doing that elsewhere in your code, but if you aren't, send it a release
when you've finished using it.
Edit
If you're deallocating arrayDetPerformance
in your dealloc
method, I'm assuming it's an instance variable? In this case, you can't assume that it doesn't already point at an object, so you should send it a release
before assigning it to the new object.
Alternatively, if it is configured as a property, just use self.arrayDetPerformance = ...
which will take care of the memory management for you.
Do not call retainCount
retainCount
is useless. The absolute retain count of an object is an implementation detail. The rule is simple; if you cause something to be retained, you must cause it to be released when you are done with it. End of story.
The memory management documentation discusses this fully.
First, retainCount
can never return zero. The only time you'll get a zero is if you happened to message nil
. This:
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 2
You are causing arrayDetail
to point to a different object on that second line. Thus, no relation between the retain count before/after that line.
When leaks tells you a leak is on a particular line like this one...
arrayDetPerformance = [[NSMutableArray alloc] initWithArray:arrayDetail];
... it is telling you that said object allocated on that line was leaked. It is not telling you that particular line was the cause of the leak. The leak is likely because you either over-retained it somewhere else or forgot to leak it.
You've said in several comments that you are "deallocating [something] in your dealloc". Show your dealloc method's implementation.
[arrayDetPerformance release]; is not written in your code;
So, its show memory leak.
精彩评论