Objective-c static instance

11,783

Solution 1

  1. It doesn't look like you create the object anywhere. You need to alloc and init the object before you can use it.
  2. You should not be retaining the static object every time someone calls +getDatabase. This will cause the object to be over retained and there is really no reason for it, once you alloc and init it then the static variable will own it and you don't need any more retains.

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.

Solution 2

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.

Share:
11,783
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    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...

  • Admin
    Admin almost 15 years
    1. In the open method it is allocated by the API I don't wanna use singleton, because it's not a typical singleton case. There will be more derived classes, and I just want to use the same database connection in all classes. (Thread safe be my problem..) So I open the connection in the beginning of the application, and close when the program terminates. Thanks for the links...