I have not been able to find a solution to my problem in similar questions. I am extracting a whole bunch of data from a sqlite database using the fmdb wrapper. I have a method in my fmdb utility class similar to this:
- (NSMutableArray *) getConnectionsForKey: (NSString *) key
{
NSString *query = [NSString stringWithFormat:@"select * from user" ];
FMResultSet *results = [database executeQuery:query];
NSMutableArray *retArray = [[ NSMutableArray alloc ] init ];
while ([ results next ]) {
NSString *fname = [ results stringForColumn:@"firstname" ];
NSString *lname = [ results stringForColumn:@"lastname" ];
NSMutableDictionary *aDictionary = [[ NSMutableDictionary alloc ]
init
];
[ aDictionary
setObject:fname
forKey:@"firstname"
];
[ aDictionary
setObject:lname
forKey:@"lastname"
];
[ retArray addObject:aDictionary ];
[ aDictionary release ];
}
[ results close ];
return retArray;
}
That stores my info in an array of dictionaries. In my view controller I make a call to my method like so:
-(void) setCurrentConnections: (NSString *) key {
if ( currentConnections != nil ) {
[ currentConnections removeAllObjects ];
}
LocalDatabase *db = [[ LocalDatabase alloc ] init ];
[ db openDatabase ];
currentConnections = [ db getConnectionsForKey:key ];
[ db closeDatabase ];
[ db release ];
}
Now everytime I call this method to update my array with new contacts, I have a consistent leak that keeps building up as I observe with the allocations tool. This happens even when I release currentConnections right after loading from the database and never call this method again so I am suspecting it is something with the database implementation. Has anyone else handled this problem?
currentConnections is leaking in 'setCurrentConnections'. Here is how I would fix it (notice I also change 'getConnectionsForKey' to return an autoreleased object).
- (NSMutableArray *) getConnectionsForKey: (NSString *) key
{
NSString *query = [NSString stringWithFormat:@"select * from user" ];
FMResultSet *results = [database executeQuery:query];
NSMutableArray *retArray = [[ NSMutableArray alloc ] init ];
while ([ results next ]) {
NSString *fname = [ results stringForColumn:@"firstname" ];
NSString *lname = [ results stringForColumn:@"lastname" ];
NSMutableDictionary *aDictionary = [[ NSMutableDictionary alloc ] init];
[ aDictionary
setObject:fname
forKey:@"firstname"
];
[ aDictionary
setObject:lname
forKey:@"lastname"
];
[ retArray addObject:aDictionary ];
[ aDictionary release ];
}
[ results close ];
return [retArray autorelease];
}
-(void) setCurrentConnections: (NSString *) key {
[ currentConnections removeAllObjects ];
[ currentConnections release];
LocalDatabase *db = [[ LocalDatabase alloc ] init ];
[ db openDatabase ];
currentConnections = [ db getConnectionsForKey:key ];
[currentConnections retain];
[ db closeDatabase ];
[ db release ];
}
You can probably skip the call to removeAllObjects
and just call release. The problem in the original code is that you were overwriting the reference to your existing currentConnection without releasing it first, therefore causing the leak.