PDA

View Full Version : Memory Leaks




Ankitthakur
Jan 23, 2009, 11:59 AM
Hi guys,
I am making a small application and at some part I am facing the memory leaks in some lines, here is the code I am submitting

NSArray *filePaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory,
NSUserDomainMask,
YES
);


NSString * recordingDirectory = [filePaths objectAtIndex: 0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *recordingDirectoryPath = [NSString stringWithString:recordingDirectory];
NSString *cachePath = [recordingDirectoryPath stringByAppendingPathComponent:@"ayisearch.plist"];
if (![fileManager fileExistsAtPath:cachePath])
{


}
else{

//Get the Current Dictionaary
NSLog(@"%@",cachePath);
NSArray *testArray = [[NSArray alloc] initWithContentsOfFile:cachePath];

NSMutableArray *testArray1 = [[NSMutableArray alloc] initWithCapacity:0];
for(int i=0; i<[testArray count];i++)
{
getProfile = [[NSMutableDictionary alloc] initWithDictionary: [testArray objectAtIndex:i]];
NSString *profileName = [getProfile objectForKey:@"name"];
NSString *imagePath = [recordingDirectoryPath stringByAppendingPathComponentrofileName];
NSString *imageName = [NSString stringWithFormat:@"%@.jpg",profileName];
NSString *imageFilePath = [imagePath stringByAppendingPathComponent:imageName];

NSURL *imgurl = [NSURL URLWithString:[getProfile objectForKey:@"img"]];
NSLog(@"finalURL: %@",imgurl);

NSData *data = [[NSData alloc] initWithContentsOfURL:imgurl];
[fileManager createDirectoryAtPath:imagePath attributes:nil];
[data writeToFile:imageFilePath atomically:NO];
[getProfile setObject:imageFilePath forKey:@"img"];
[testArray1 addObject:getProfile];
[data release];
[getProfile release];
}
testArray = [NSArray arrayWithArray:testArray1];
[testArray1 release];


getProfile = [NSMutableDictionary dictionaryWithDictionary:[testArray objectAtIndex:0]];

NSMutableArray *updateTestArray = [NSMutableArray arrayWithArray:testArray];
[updateTestArray removeObjectAtIndex:0];
testArray = updateTestArray;
updateTestArray = nil;
[testArray writeToFile:cachePath atomically:NO];

NSUInteger *noOfProfiles = (NSUInteger *) [testArray count];
NSLog(@"no of records we are getting from the server are ");
if(noOfProfiles <= kCacheProfiles)
{

[NSThread detachNewThreadSelector:@selector(doSearch) toTarget:self withObject:nil];

}
[testArray release];
}

The colored parts are sending leaks, please guide me here. Thanks in advance



xsmasher
Jan 23, 2009, 12:38 PM
I believe
testArray = updateTestArray;
is your problem. You're throwing array the old testArray there, and it never gets released. "release" affects the object pointed to by the variable, not the variable itself. testArray now points to updateTestArray, and there is no way to release the old array (it gets leaked.)

I'll go you one better, this entire section

NSMutableArray *updateTestArray = [NSMutableArray arrayWithArray:testArray];
[updateTestArray removeObjectAtIndex:0];
testArray = updateTestArray;
updateTestArray = nil;


can be replaced with this:

[testArray removeObjectAtIndex:0];

*If* testArray were declared and init'ed as an NSMutableArray in the first place.


Addendum: This line is bad too
testArray = [NSArray arrayWithArray:testArray1];
You're throwing away the old array and replacing it with a new one. Either release the old array before you do this, or rewrite it so you're not leaking the array.

youPhone
Jan 23, 2009, 04:58 PM
actually, the way he has it set up, the for loop terminates depending on the value of [testArray count]

He should not edit the contents of testArray while in the for loop


Ankitthakur, you may also consider using fast enumeration

for (NSDictionary *aDictionary in testArray) {
...
getProfile = [NSMutableDictionary dictionaryWithDictionary:aDictionary];
...
}


So now you don't have to keep doing objectAtIndex:i
Also, this way you don't have to [getProfile release], as it will be autoreleased