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

问题描述 投票:1回答:1

我正在尝试打开一个随时可访问的SQLite3数据库。我创建了一个DBModel类以及一个DBManager。该模型是NSString dbNameNSString 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
    }
}

dbmDBManagersiteDBModel是与我们的网站数据相关的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;
        }
    }
ios objective-c sqlite
1个回答
1
投票

您的开放式方法正是导致问题的原因:

- (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;
    }
}

如果在打开调用之后立即设置断点,并且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
© www.soinside.com 2019 - 2024. All rights reserved.