Memory Leaks

Discussion in 'iOS Programming' started by Ankitthakur, Jan 23, 2009.

  1. Ankitthakur macrumors newbie

    Joined:
    Jan 23, 2009
    #1
    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:mad:"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:mad:"name"];
    NSString *imagePath = [recordingDirectoryPath stringByAppendingPathComponentrofileName];
    NSString *imageName = [NSString stringWithFormat:mad:"%@.jpg",profileName];
    NSString *imageFilePath = [imagePath stringByAppendingPathComponent:imageName];

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

    NSData *data = [[NSData alloc] initWithContentsOfURL:imgurl];
    [fileManager createDirectoryAtPath:imagePath attributes:nil];
    [data writeToFile:imageFilePath atomically:NO];
    [getProfile setObject:imageFilePath forKey:mad:"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:mad:selector(doSearch) toTarget:self withObject:nil];

    }
    [testArray release];
    }

    The colored parts are sending leaks, please guide me here. Thanks in advance
     
  2. xsmasher macrumors regular

    xsmasher

    Joined:
    Jul 18, 2008
    #2
    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
    Code:
    NSMutableArray *updateTestArray = [NSMutableArray arrayWithArray:testArray];
    [updateTestArray removeObjectAtIndex:0];
    testArray = updateTestArray;
    updateTestArray = nil;
    
    can be replaced with this:
    Code:
    [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.
     
  3. youPhone macrumors member

    Joined:
    Sep 8, 2008
    #3
    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
    Code:
    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
     

Share This Page