I’m using Leaks, and I believe I’ve narrowed down the problem, and I’m sure my inexperience has something to do with it. If you see a failure in my logic (as in, there’s obviously a simpler way to do this), please let me know.
In this case we’re working with 3 classes, a Row class that describes rows in a database, a Database class that contains getRow, insertRow type functions, and a ViewController class.
inside Row.h:
@interface Row : NSObject {
int rowID;
NSString *FirstName;
NSString *LastName;
}
@property (nonatomic) int rowID;
@property (nonatomic, retain) NSString *FirstName; <--see comments below
@property (nonatomic, retain) NSString *LastName; <--see comments below
@end
Hopefully this one is pretty obvious, creates an object that i’m going to push data I pull from the database into.
inside Database.m
-(Row *) getRow {
NSLog(@"Inside getRow");
Row *holder = [[[Row alloc] init] autorelease];
...All the SQL stuff... (Select * from table where id = 1), etc.
char *first = (char *)sqlite3_column_text(statement, 1);
char *last = (char *)sqlite3_column_text(statement, 2);
holder.rowID = sqlite3_column_int(statement, 0);
holder.FirstName = [NSString stringWithUTF8String:first];
holder.LastName = [NSString stringWithUTF8String:last];
return holder;
}
Also, hopefully, fairly self explanatory. Get a specific row from the database, put the info into a Row object (see Row.h).
inside ViewController.m
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
dataB = [[Database alloc] init];
[dataB openDB];
currentRow = [[dataB getRow] retain]; <--See comments below.
firstNameLabel.text = currentRow.FirstName;
}
-(IBAction)btnGetLastName:(id)sender{
lastNameLabel.text = currentRow.LastName; <--See comments below.
[currentRow release];
currentRow = [dataB getRow];
}
Basically here the view controller give you the first name, and when you click on a button it displays the last name.
So, I’m leaking, and I’ve narrowed it down to every time I press btnGetLastName. If I don’t retain
currentRow = [[dataB getRow] retain];
I crash at
lastNameLabel.text = currentRow.LastName;
(Message sent to deallocated instance).
I’ve been banging my head into the wall for a couple days on this and I would really like to move forward from here, so if anyone can offer help, it would be greatly appreciated. I will also say that this has all been a learning experience, so in some cases if you have to ask “Why did you do this?” the answer may be “because I’m dumb”. Hopefully the problem here is glaring to someone.
Alright, there are a couple of things that I am seeing here that are incorrect. First of all, you should probably make
currentRowa retained property, that way you do not have to retain it and release it yourself. Also, make sure your-deallocmethod of your Row class look as follows:Make your currentRow a property like so:
Then, assign it like
self.currentRow = aRow. Also note that you will need to setself.currentRow = nilin the dealloc method as well. Your app is most likely crashing because you are not retaining currentRow on the linecurrentRow = [dataB getRow];.I would also like to point out that it is bad convention to capitalize the first letter of an instance variable.