开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜