View Full Version : Don't get how have a not autorelease object in class definition

Jan 8, 2009, 10:07 AM
Hi, I have this:

@interface Db : NSObject {
NSString *path;
FMDatabase* theDb;
@property(readonly, retain) FMDatabase *theDb;
@property (readonly, nonatomic) NSString *path;

Then, I create:

- (id)initWithName:(NSString *)name{
self = [super init];

if (self) {
path = [name copy];
theDb = [[FMDatabase alloc] initWithPath:path];

return self;

- (void)dealloc
NSLog(@"Deallocating %@", self);
[theDb release]; <----FAIL!!!
[path release];
[super dealloc];

I don't understand why fail in the release part, if I say retain in the property. Happend the same thing if I put retain in the init.

If I remove this line, I don't get a error, but that not sound rigth to me....

Jan 8, 2009, 11:21 AM
Have you synthesized the property accessors? Where do you use them? You should be using something like

self.theDb = ...

to actually use the accessors which have been synthesized...

Jan 9, 2009, 08:36 AM
Thank you, that do the trick ;)

Luke Redpath
Jan 10, 2009, 07:15 PM
However, if you do use your accessor and do this in your init method:

self.theDb = [[FMDatabase alloc] initWithPath:path];

And then do this in your dealloc:

[theDb release];

Then you will have a memory leak. When you call the initWithPath method, the object returned has a retain count of 1. You then pass it into the setTheDb: method (this is the synthesized setter method used when you do self.theDb=) it sends it a retain giving it a retain count of 2. Then you release it in dealloc, bringing it back down to 1. So it leaks.

Your original code was correct. By assigning to the instance variable directly, it only has a retain count of 1 and should be released correctly in dealloc. If you really want to use your setter, you should do this:

_theDb = [[FMDatabase alloc] initWithPath:path];
self.theDb = theDb;
[_theDb release];

But that seems a bit pointless (unless your setter does anything special).

Out of interest, your FMDatabase initWithPath method isn't returning an autoreleased object is it? It shouldn't be.