Need help in finding a memory leak in copying Sqlite Database to Mutable array
I seem to be having a 1.19 KB leak somewhere in the following code. opening up the call tree in instruments, I have narrowed down the leaks to the following:
61.开发者_JS百科8% of the leaks are coming from +[NSString stringWithUTF8String:]
38.1% of the leaks are coming from +[NSNumber numberWithDouble:]
-(void) readMinesFromDatabase
{
NSLog(@" Setup the database object");
sqlite3 *database;
// Init the Array
northernMines = [[NSMutableArray alloc] init];
nCentralMines = [[NSMutableArray alloc] init];
centralMines = [[NSMutableArray alloc] init];
southernMines = [[NSMutableArray alloc] init];
//NSLog(@" pre if statement");
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "SELECT * FROM mines";
//NSLog(@"pre 2nd if statement");
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) != SQLITE_OK)
{
NSLog( @"Error: Failed to prepare stmt with message %s", sqlite3_errmsg(database));
}
else
{
// Loop through the results and add them to the feeds array
NSLog(@"pre loop");
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSString *name;
NSString *com;
NSString *county;
NSNumber *lat;
NSNumber *longit;
// Read the data from the result row
//deals with null strings in the name and commodity fields of the database
//NSLog(@"ered the loop");
if (sqlite3_column_text(compiledStatement, 3) != NULL) {
name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
}
else {
name = @"";
}
if (sqlite3_column_text(compiledStatement, 10) != NULL) {
com = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 10)];
}
else {
com = @"";
}
//latitude and longitudes
lat = [NSNumber numberWithDouble:(double )sqlite3_column_double(compiledStatement, 4)];
longit = [NSNumber numberWithDouble:(double )sqlite3_column_double(compiledStatement, 5)];
//NSLog(@"long %@",longit);
// Create a new object with the data from the database
Mine *mine = [[Mine alloc] initWithMineName:name latitudeInitial:lat longitudeInitial:longit commodity:com];
// Add the object to the animals Array
county = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 8)];
if([county isEqualToString:@"Butte"] || [county isEqualToString:@"Plumas"] || [county isEqualToString:@"Yuba"] || [county isEqualToString:@"Sierra"])
{
[northernMines addObject:mine];
}
else if([county isEqualToString:@"Nevada" ]|| [county isEqualToString:@"Placer"] || [county isEqualToString:@"El Dorado"] || [county isEqualToString:@"Sutter"])
{
[nCentralMines addObject:mine];
}
else if([county isEqualToString:@"Amador"] || [county isEqualToString:@"Sacramento"] || [county isEqualToString:@"Calaveras"] || [county isEqualToString:@"San Joaquin"] || [county isEqualToString:@"Stanislaus"])
{
[centralMines addObject:mine];
}
else if([county isEqualToString:@"Tuolumne"] ||[county isEqualToString:@"Mariposa"] || [county isEqualToString:@"Madera"] || [county isEqualToString:@"Merced"])
{
[southernMines addObject:mine];
}
else
{
}
[mine release];
//[name release];
//[com release];
//[county release];
//[lat release];
//[longit release];
}
NSLog(@"done with loop");
//[mines addObject:@"nil"];
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
the mine object implementation file is:
#import "Mine.h"
@implementation Mine
@synthesize mineName, latitudeInitial, longitudeInitial, commodity;
-(id)initWithMineName:(NSString *)n latitudeInitial:(NSNumber *)l longitudeInitial:(NSNumber *)g commodity:(NSString *)c
{
self.mineName = n;
self.latitudeInitial = l;
self.longitudeInitial = g;
self.commodity = c;
return self;
}
@end
Well, it is a little hard to tell because of the indentation where the function ends (is this the entire function?) but I believe you are forgetting to release the 4 arrays that you are allocating at the beginning of the function. By leaking the arrays you are also leaking their contents.
Edit - for the initializer code you added:
I am not sure if this has anything to do with the memory leaks but I noticed that the initializer is not implemented correctly:
you should call
init
onsuper
and updateself
(more details here)of this I am not 100% sure, but I think you should not send messages (call methods) to the current object from inside the init method, and by using the dot notation you are actually calling the setter methods (but again, I am not really sure of this one)
I suppose that the properties are declared as (retain)
and that you release them in the dealloc
method. Which would be correct.
I can't really see anything else wrong with the code you showed. Maybe the problem is not exactly here (just an idea).
Edit 2 - example initializer
You should spend some time reading the Apple documentation, it has plenty of examples.
Here is my version (I hope it doesn't have too many mistakes):
-(id)initWithMineName:(NSString *)n latitudeInitial:(NSNumber *)l longitudeInitial:(NSNumber *)g commodity:(NSString *)c {
// Assign self to value returned by super's designated initializer
// Designated initializer for NSObject is init
self = [super init];
if (self) {
mineName = [n retain];
latitudeInitial = [l retain];
longitudeInitial = [g retain];
commodity = [c retain];
}
return self;
}
Just a thought, but could the memory leak be in the Mine object initializer ( -[Mine initWithMineName: latitudeInitial: longitudeInitial: commodity:] ) ??
精彩评论