Reputation:
I'd like to create database based models, so I wanna use my own DatabaseModel class to manage the database connection, and every class that uses database is derived from it (it would be a mapping between the model and the table). I'm using a sqlite API.
Since I need only one database connection instance, I created a static variable to store the connection instance
DatabaseModel.h --------------- @interface DatabaseModel : NSObject { } // the connection instance static FMDatabase *database; +(BOOL) open; +(void) close; +(id)getDatabase; @end DatabaseModel.m --------------- // Is it necassary? static FMDatabase *database = nil; @implementation DatabaseModel +(BOOL) open { // make connection (doodled code) database = [DBAPI open]; } +(void) close { // ... } +(id)getDatabase { // Throws bad_memory_access [database retain]; return database; } @end MyClass.h --------- @interface MyClass : DatabaseModel { } -(void) foobar; @end MyClass.m --------- @implementation MyClass -(void) foobar { // This assign doesn't work database = [DatabaseModel getDatabase]; } @end
In this case [database retain] throws a bad_access exception. I don't understand exactly, when database is a static variable, why I get this message...
Upvotes: 2
Views: 11802
Reputation: 21882
In your +open
method, you have:
database = [DBAPI open];
If DBAPI is following standard Cocoa memory rules, the returned instance is not retained (usually it's autoreleased). So by the time you access it in +getDatabase
the instance may already have been released.
Simple fix would be to retain the instance:
database = [[DBAPI open] retain];
A better approach would be to adopt the singleton pattern as others have mentioned.
Upvotes: 1
Reputation:
Sorry guys!
It was my mistake. In Open() function the API asks for an (NSString*) sqlite path. And I forgot to retain that variable. (I'm sometimes in trouble with objective-c memory management, sorry)
Now I'm creating the variable without static keyword on the base class, and using extern keyword to reach in the subclasses, and does it work.
With static keyword it's invisible from derived classes...
Upvotes: 0
Reputation: 25011
Cocoa has a design pattern call Singleton that would work well here. You create a single instance of a class and then have a method (often along the lines of +sharedClassName) that returns that instance.
For more reading there is some good information at CocoaDev regarding the singleton design pattern and Cocoa with Love has a good article on Singletons, AppDelegates and top-level data.
Upvotes: 3
Reputation: 872
This error actually saying that the database variable is still null. I dont see any init call of the database variable or allocation. Am I missing anything?
Upvotes: 0