NSMutableArray memory leak when reloading objects

Posted by Davin on Stack Overflow See other posts from Stack Overflow or by Davin
Published on 2012-06-17T15:15:27Z Indexed on 2012/06/17 15:15 UTC
Read the original article Hit count: 220

I am using Three20/TTThumbsviewcontroller to load photos. I am struggling since quite a some time now to fix memory leak in setting photosource. I am beginner in Object C & iOS memory management. Please have a look at following code and suggest any obvious mistakes or any errors in declaring and releasing variables.

-- PhotoViewController.h

 @interface PhotoViewController : TTThumbsViewController <UIPopoverControllerDelegate,CategoryPickerDelegate,FilterPickerDelegate,UISearchBarDelegate>{
......
NSMutableArray *_photoList;

......
@property(nonatomic,retain) NSMutableArray *photoList;

-- PhotoViewController.m

@implementation PhotoViewController
....

@synthesize photoList;
.....

- (void)LoadPhotoSource:(NSString *)query:(NSString *)title:(NSString* )stoneName{


NSLog(@"log- in loadPhotosource method");


if (photoList == nil)
    photoList = [[NSMutableArray alloc] init ];

[photoList removeAllObjects];



@try {
    sqlite3 *db;
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    NSString *dbPath = [documentsPath stringByAppendingPathComponent: @"DB.s3db"];
    BOOL success = [fileMgr fileExistsAtPath:dbPath];
    if(!success)
    {
        NSLog(@"Cannot locate database file '%@'.", dbPath);
    }

    if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
    {
        NSLog(@"An error has occured.");
    }


    NSString *_sql = query;//[NSString stringWithFormat:@"SELECT * FROM  Products where CategoryId = %i",[categoryId integerValue]];
    const char *sql = [_sql UTF8String];
    sqlite3_stmt *sqlStatement;
    if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
    {
        NSLog(@"Problem with prepare statement");
    }

    if ([stoneName length] != 0)
    {
    NSString *wildcardSearch = [NSString stringWithFormat:@"%@%%",[stoneName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];

    sqlite3_bind_text(sqlStatement, 1, [wildcardSearch UTF8String], -1, SQLITE_STATIC);
    }


    while (sqlite3_step(sqlStatement)==SQLITE_ROW) {

        NSString* urlSmallImage = @"Mahallati_NoImage.png";
        NSString* urlThumbImage = @"Mahallati_NoImage.png";


        NSString *designNo = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
        designNo = [designNo stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

        NSString *desc = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,7)];
        desc = [desc stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

        NSString *caption = designNo;//[designNo stringByAppendingString:desc];
        caption = [caption stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];



        NSString *smallFilePath = [documentsPath stringByAppendingPathComponent: [NSString stringWithFormat:@"Small%@.JPG",designNo] ];
        smallFilePath = [smallFilePath stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        if ([fileMgr fileExistsAtPath:smallFilePath]){
            urlSmallImage = [NSString stringWithFormat:@"Small%@.JPG",designNo];
        }

        NSString *thumbFilePath = [documentsPath stringByAppendingPathComponent: [NSString stringWithFormat:@"Thumb%@.JPG",designNo] ];
        thumbFilePath = [thumbFilePath stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

        if ([fileMgr fileExistsAtPath:thumbFilePath]){
            urlThumbImage = [NSString stringWithFormat:@"Thumb%@.JPG",designNo];
        }




        NSNumber *photoProductId = [NSNumber numberWithInt:(int)sqlite3_column_int(sqlStatement, 0)];
         NSNumber *photoPrice = [NSNumber numberWithInt:(int)sqlite3_column_int(sqlStatement, 6)];

          char *productNo1 = sqlite3_column_text(sqlStatement, 3);
        NSString* productNo;
        if (productNo1 == NULL)
            productNo = nil;
        else
            productNo = [NSString stringWithUTF8String:productNo1];

        Photo *jphoto = [[[Photo alloc] initWithCaption:caption
                                               urlLarge:[NSString stringWithFormat:@"documents://%@",urlSmallImage] 
                                               urlSmall:[NSString stringWithFormat:@"documents://%@",urlSmallImage] 
                                               urlThumb:[NSString stringWithFormat:@"documents://%@",urlThumbImage]
                                                   size:CGSizeMake(123, 123) 
                                              productId:photoProductId
                                                  price:photoPrice
                                                description:desc
                          designNo:designNo 
                                              productNo:productNo
                          ]  autorelease];



        [photoList addObject:jphoto];
        [jphoto release];



    }


}
@catch (NSException *exception) {
    NSLog(@"An exception occured: %@", [exception reason]);
}



self.photoSource = [[[MockPhotoSource alloc]
                     initWithType:MockPhotoSourceNormal
                     title:[NSString stringWithFormat: @"%@",title]
                     photos: photoList
                     photos2:nil] autorelease];

}

Memory leaks happen when calling above LoadPhotosource method again with different query... I feel its something wrong in declaring NSMutableArray (photoList), but can't figure out how to fix memory leak. Any suggestion is really appreciated.

© Stack Overflow or respective owner

Related posts about ios

Related posts about memory-leaks