2009-06-07 2 views
2

Я хотел бы создать модели на базе базы данных, поэтому я хочу использовать свой собственный класс DatabaseModel для управления соединением с базой данных, и каждый класс, который использует базу данных, выводится из него (это будет отображение между модель и таблица). Я использую sqlite API.Objective-c static 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 

В этом случае [базы данных сохраняют] бросает bad_access исключения. Я точно не понимаю, когда база данных является статической переменной, почему я получаю это сообщение ...

ответ

0

Эта ошибка на самом деле говорит о том, что переменная базы данных по-прежнему равна нулю. Я не вижу никакого вызова init из базы данных или распределения. Я ничего не теряю?

3
  1. Не похоже, чтобы вы создали объект в любом месте. Вам нужно выделить и начать объект, прежде чем вы сможете использовать .
  2. Вы не должны сохранять статический объект каждый раз, когда кто-то звонит + getDatabase. Это приведет к тому, что объект будет сохранен, и на самом деле нет причин для этого, как только вы выберете и запустите его, тогда статическая переменная будет им владеть, и вам больше не понадобится.

Какао имеет дизайн-шаблон Singleton, который будет хорошо работать здесь. Вы создаете один экземпляр класса, а затем имеете метод (часто по строкам + sharedClassName), который возвращает этот экземпляр.

Для получения дополнительной информации в CocoaDev имеется некоторая хорошая информация относительно singleton design pattern, а у Cocoa with Love есть хорошая статья на Singletons, AppDelegates and top-level data.

+0

1. В открытом методе выделяется API Я не хочу использовать singleton, потому что это не типичный одноэлементный случай.Будет больше производных классов, и я просто хочу использовать одно и то же соединение с базой данных во всех классах. (Thread safe - моя проблема ..) Поэтому я открываю соединение в начале приложения и закрываю, когда программа завершается. Спасибо за ссылки ... – 2009-06-07 12:59:54

0

Извините, ребята!

Это была моя ошибка. В функции Open() API запрашивает (sqlite) путь (NSString *). И я забыл сохранить эту переменную. Извините)

Теперь я создаю переменную без статического ключевого слова в базовом классе и используя ключевое слово extern для достижения в подклассах и работает ли она.

С помощью статического ключевого слова она невидима из производных классов ...

+0

Статическая переменная доступна только в объявленном файле. Ваши подклассы должны были бы вызвать метод + getDatabase, чтобы получить ссылку на него. –

1

В вашем методе +open, у вас есть:

database = [DBAPI open]; 

Если DBAPI имеет следующие стандартные правила какао памяти, возвращаемый экземпляр не сохраняется (обычно он автореализован). Поэтому к тому моменту, когда вы получите доступ к нему в +getDatabase, экземпляр, возможно, уже был выпущен.

Простое исправление было бы сохранить экземпляр:

database = [[DBAPI open] retain]; 

Лучше было бы принять одноплодной шаблон, как уже упоминалось.

Смежные вопросы