Search code examples
iosobjective-cuiimagensdatafmdb

NSData and UIImage not released in iOS7


I have a big table in SQLite where photos are stored with good resolution so they have a big size… so I am trying to resize these images and updating the DB table in the same process. I am using FMDB wrapper for working with SQLite DB.

Well, with instruments I can see NSData and UIImage is not being released and memory grows quickly so it makes my app close.

What could I do?

Here it is the code:

FMResultSet *aFMResultSet = [database executeQuery:@"SELECT id, image FROM Images WHERE LENGTH(image)> 1000000;" ];

while([aFMResultSet next]){

    int aId = [aFMResultSet intForColumn:@"id"];

    NSData *aDataImage = [aFMResultSet dataForColumn:@"image"];
    UIImage* aImage = [UIImage imageWithData:aDataImage];

    UIImage *aResizedImage = [Utils resizedImage:aImage withRect:CGRectMake(0, 0, 324, 242)]; //(2592x1936)/16
    NSData *aDataResizedThumbnail = UIImageJPEGRepresentation(aResizedImage,0.5f);

    [database executeUpdate:@"UPDATE Images SET image = ? WHERE id = ?;", aDataResizedThumbnail, [NSNumber numberWithInt:aId],nil];

}


Solution

  • Due to the loop, the system might never get a chance to free the memory not needed anymore.

    To force the system to do so, wrap the inside of your loop in an autoreleasepool, like this:

    FMResultSet *aFMResultSet = [database executeQuery:@"SELECT id, image FROM Images WHERE LENGTH(image)> 1000000;" ];
    
    while([aFMResultSet next]){
        int aId = [aFMResultSet intForColumn:@"id"];
        @autoreleasepool {
            NSData *aDataImage = [aFMResultSet dataForColumn:@"image"];
            UIImage* aImage = [UIImage imageWithData:aDataImage];
    
            UIImage *aResizedImage = [Utils resizedImage:aImage withRect:CGRectMake(0, 0, 324, 242)]; //(2592x1936)/16
            NSData *aDataResizedThumbnail = UIImageJPEGRepresentation(aResizedImage,0.5f);
    
            [database executeUpdate:@"UPDATE Images SET image = ? WHERE id = ?;", aDataResizedThumbnail, [NSNumber numberWithInt:aId],nil];
        }
    }