带有无效数据库连接指针的 Objective-C API 调用

Aar*_* M. 5 sqlite objective-c ios

我正在尝试打开一个SQLite3可以随时访问的数据库。我创建了一个DBModel类以及一个DBManager. 模型是NSString dbNameNSString dbPath和 SQLite3 db,以及BOOL dbOpened.

我创建这个类的原因是为了帮助管理SQLite我们以前的开发人员创建的大约十几个不同的数据库,而不是在各处创建、打开、关闭和删除这些数据库,我决定创建管理器来在一个地方处理所有这些。

一个简单的例子是:

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

dbmDBManagersiteDBModelDBModel与我们的网站数据相关的查询和声明均已事先声明。

我得到的错误是:

使用无效数据库连接指针的 API 调用。

我在声明 sqlite3 *db 并在同一代码块中打开它时看到了这项工作,但我想防止每次我想运行查询时都必须在不同的视图控制器中声明这些变量,这也是我创建类来处理这些任务。

数据库模型

@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;
Run Code Online (Sandbox Code Playgroud)

数据库管理器

    @interface DBManager : NSObject {
        DBModel *sitesDBModel;
    }

    @property (nonatomic, retain) DBModel *sitesDBModel;
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

小智 3

您的打开方法是导致您出现问题的原因:

- (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;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您在 open 调用以及 db 和 dbModel.db 的地址之后设置断点,po您将看到 dbModel.db 未指向打开的数据库连接:

(lldb) po db
0x00007fb242c1e500

(lldb) po dbModel.db
<nil>
Run Code Online (Sandbox Code Playgroud)

建立连接指针后,您需要将其指向打开的连接:

- (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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在如果你po他们应该匹配:

(lldb) po db
0x00007f877bd04a30

(lldb) po dbModel.db
0x00007f877bd04a30
Run Code Online (Sandbox Code Playgroud)