John Shehata
John Shehata

Reputation: 1

Memory Leak in Objective C Class iOS

I have searched high and low to try to resolve this memory leak, but I can't figure out how to make it go away. I have several classes that I use to connect to my sqlite dbase and pull information.

When I run the app using performance tools, leaks, I keep finding that all of my classes leak memory.

Below is the code that I have. Any help resolving this leak would be greatly appreciated.

tbl_materialsList.h

@interface tbl_materialsList : NSObject {

 NSInteger materialListID;
 NSString *shoppingListID;
 NSString *projectID;
 NSString *materialName;
 NSString *numberOfUnits;
 NSString *purchased;
 NSString *totalPrice;
 NSString *unitPrice;

}

@property (nonatomic, readonly) NSInteger materialListID;
@property (nonatomic, retain) NSString *shoppingListID;
@property (nonatomic, retain) NSString *projectID;
@property (nonatomic, retain) NSString *materialName;
@property (nonatomic, retain) NSString *numberOfUnits;
@property (nonatomic, retain) NSString *purchased;
@property (nonatomic, retain) NSString *totalPrice;
@property (nonatomic, retain) NSString *unitPrice;

- (id)getDataToDisplay:(NSString *)dbPath :(NSString *)selectStatement;
- (void)saveData:(NSString *)dbPath :(NSString *)selectStatement;
- (id)initWithPrimaryKey:(NSInteger)pk;

tbl_materialsList.m

- (id)getDataToDisplay:(NSString *)dbPath :(NSString *)selectStatement {


 // Init the data Array
 NSMutableArray *data = [[NSMutableArray alloc] init];

 if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {

  NSString *sql = selectStatement; //"select * from tbl_projects";
  sqlite3_stmt *selectstmt;
  if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &selectstmt, NULL) == SQLITE_OK) {
   //loop thru and fill the array
   while(sqlite3_step(selectstmt) == SQLITE_ROW) {
    //reading the results
    NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
    tbl_materialsList *listObj = [[tbl_materialsList alloc] initWithPrimaryKey:primaryKey];
    listObj.shoppingListID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
    listObj.projectID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)];
    listObj.materialName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)];
    listObj.numberOfUnits = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 4)];
    listObj.purchased = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 5)];
    listObj.totalPrice = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 6)];
    listObj.unitPrice = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 7)];

    [data addObject:listObj];
    [listObj release];
   }
  }

  //release the compiled statment from memory
  sqlite3_finalize(selectstmt);

 }

 sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory.

 return data;

}

Upvotes: 0

Views: 671

Answers (4)

Yuji
Yuji

Reputation: 34185

An unrelated advice:

Never return an object as (id) unless it's absolutely necessary. For example, your getDataToDisplay:: should be

-(NSMutableArray*)getDataToDisplay:(NSString *)dbPath :(NSString *)selectStatement;

That way, you can get more compiler warnings when you make a mistake.

I guess there's an iPhone programming book which promotes this bad custom. The author of the book should be leashed and the book should be burned ... :p

Upvotes: 0

Jasarien
Jasarien

Reputation: 58448

Your final line:

return data;

should be:

return [data autorelease];

Unless, of course, you intend the returned data object to be owned by the caller, then you should make the method name conform to the Objective-C naming conventions in that method that return objects with a retain count of +1 should contain one of the words "copy" "create" or "new";

But I suspect that this isn't what you intend.

Upvotes: 3

Peter
Peter

Reputation: 1031

Does your tbl_materialslist implement a dealloc that sets all your retain properties to nil? If not, they are all leaking even though your listObj is being released.

Upvotes: 1

Sheehan Alam
Sheehan Alam

Reputation: 60859

strings should be @property(nonatomic,copy) first of all, and you need to release data. [data release];

Upvotes: 0

Related Questions