在iPhone App初始化中访问两个单独查询的SQLite DB

时间:2009-11-03 05:44:13

标签: iphone objective-c sqlite

我成功访问了我的数据库,以获取应用启动时的城市列表。我之后尝试对它运行第二个查询以获取状态列表,但所有发生的事情都是我的应用程序在控制台中没有可用的错误而爆炸(只是说“程序接收信号:EXEC_BAD_ACCESS”,仅此而已)。

这是代码,我希望有人可以向我解释我做错了什么:

-(void) initializeDatabase{
// The database is stored in the application bundle
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"mydatabase.sqlite"];

// Open the database.  The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK){
    [self initializeCities:database];
    [self initializeStates:database];
} else {
    // Even though the open failed, call close to properly clean up resources.
    sqlite3_close(database);
    NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(database));
    // Additional error handling, as appropriate...
}
    }

-(void) initializeCities:(sqlite3 *)db {
NSMutableArray *cityArray = [[NSMutableArray alloc] init];
self.cities = cityArray;
[cityArray release];

// Get the primary key for all cities.
const char *sql = "SELECT id FROM my_table ORDER BY state";
sqlite3_stmt *statement;

if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) == SQLITE_OK){
    while (sqlite3_step(statement) == SQLITE_ROW){
        int primaryKey = sqlite3_column_int(statement, 0);
        City *city = [[City alloc] initWithPrimaryKey:primaryKey database:db];
        [cities addObject:city];
        [city release];
    }
}

// "Finalize" the statement - releases the resources associated with the statement.
sqlite3_finalize(statement);
}

-(void) initializeStates:(sqlite3 *)db {
NSMutableArray *statesArray = [[NSMutableArray alloc] init];
self.states = statesArray;
[statesArray release];

// Get the primary key for all cities.
const char *sql = "SELECT DISTINCT state FROM my_table ORDER BY state";
sqlite3_stmt *statement;

if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) == SQLITE_OK){
    // We "step" through the results - once for each row
    while (sqlite3_step(statement) == SQLITE_ROW){
        NSString *state;
        state = (NSString *)sqlite3_column_text(statement, 0);

        [states addObject:state];
        [state release];
    }
}

// "Finalize" the statement - releases the resources associated with the statement.
sqlite3_finalize(statement);
}

我无法调试此代码,因为调试器根本不会到达我的断点。 如果我删除了initializeStates方法,应用程序将按预期工作(没有状态列表的albiet)。

2 个答案:

答案 0 :(得分:1)

你的问题是:

NSString *state = (NSString *)sqlite3_column_text(statement, 0);

根据the documentationsqlite3_column_text()会返回char*,而不是NSString*

编辑:如果您使用了包装器,则不会遇到此问题;)

答案 1 :(得分:1)

您正在发布“状态”而未分配它。尝试这样的事情:

while (sqlite3_step(statement) == SQLITE_ROW){
    NSString *state = [[NSString alloc] initWithCString:(char*)sqlite3_column_text(statement, 0) encoding:NSASCIIStringEncoding];
    //state = (NSString *)sqlite3_column_text(statement, 0);

    [states addObject:state];
    [state release];
}

更新:在上面添加强制转换以修复编译器警告