Вызов API Objective-C с неверным указателем соединения с базой данных - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь открыть базу данных SQLite3 для доступа в любое время.Я создал DBModel класс, а также DBManager.Модель - NSString dbName, NSString dbPath и SQLite3 db, а также BOOL dbOpened.

. Причина, по которой я создал этот класс, состоит в том, чтобы помочь управлять дюжиной различных SQLite db наших предыдущих разработчиковсоздал, и вместо того, чтобы создавать, открывать, закрывать, удаляя их повсюду, я решил создать менеджер для обработки всего этого в одном месте.

Быстрый пример:

if(sqlite3_prepare_v2(dbm.sitesDBModel.db,query , -1, &statement, NULL) == SQLITE_OK) {
    if(sqlite3_step(statement) == SQLITE_DONE) {
        //do stuff here
    }
}

dbm - это DBManager, siteDBModel - это DBModel, относящиеся к нашему сайту. Данные, запросы и операторы ранее были объявлены.

Полученная ошибка:

Вызов API с недопустимым указателем соединения с базой данных.

Я видел эту работу при объявлении sqlite3 * db и открытии его в одном и том же блоке кода, но я хочу предотвратить объявление этих переменных в разныхпросматривать контроллеры каждый раз, когда я хочу выполнить запрос, поэтому я снова создал классы для обработки этих задач.

DBModel

@interface DBModel : NSObject {
        NSString    *dbName;
        NSString    *dbTempName;
        NSString    *dbPath;
        NSString    *dbTempPath;
        sqlite3     *db;
        BOOL        dbOpen;
    }

    @property (nonatomic, retain) NSString  *dbName;
    @property (nonatomic, retain) NSString  *dbTempName;
    @property (nonatomic, retain) NSString  *dbPath;
    @property (nonatomic, retain) NSString  *dbTempPath;
    @property (atomic, readwrite) sqlite3   *db;
    @property (atomic, readwrite) BOOL      dbOpen;

DBManager

    @interface DBManager : NSObject {
        DBModel *sitesDBModel;
    }

    @property (nonatomic, retain) DBModel *sitesDBModel;

Реализация для DBManager

    -(void)createDB:(DBModel *)dbModel {
        NSFileManager *fileManager  = [NSFileManager defaultManager];
        BOOL success                = [fileManager fileExistsAtPath:dbModel.dbPath];

        if(!success) {
            NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbModel.dbName];
            [fileManager copyItemAtPath:databasePathFromApp toPath:dbModel.dbPath error:nil];
        }
    }

    -(void)openDB:(DBModel *)dbModel {
        sqlite3 *db = dbModel.db;
        if(sqlite3_open([dbModel.dbPath UTF8String], &db) == SQLITE_OK) {
            dbModel.dbOpen = YES;
        }
        else {
            dbModel.dbOpen = NO;
        }
    }

1 Ответ

0 голосов
/ 18 сентября 2018

Ваш метод открытия - вот что вызывает у вас проблему:

- (void)openDB:(DBModel *)dbModel {
    dbModel.db = nil;
    sqlite3 *db = dbModel.db;
    if(sqlite3_open([dbModel.dbPath UTF8String], &db) == SQLITE_OK) {
        dbModel.dbOpen = YES;
    }
    else {
        dbModel.dbOpen = NO;
    }
}

Если вы установите точку останова сразу после вызова open и po адреса для db и dbModel.db, вы увидите, чтоdbModel.db не указывает на соединение с открытой базой данных:

(lldb) po db
0x00007fb242c1e500

(lldb) po dbModel.db
<nil>

Вам нужно указать на открытое соединение после установления указателя соединения:

- (void)openDB:(DBModel *)dbModel {
    sqlite3 *db = nil;
    if(sqlite3_open([dbModel.dbPath UTF8String], &db) == SQLITE_OK) {
        dbModel.dbOpen = YES;
        // set our pointer to the open connection after establishing
        dbModel.db = db;
    }
    else {
        dbModel.dbOpen = NO;
    }
}

Теперь, если вы po, они должны совпадать:

(lldb) po db
0x00007f877bd04a30

(lldb) po dbModel.db
0x00007f877bd04a30
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...