我有一个应用程序,我多次访问SQLite数据库..但是,一旦我访问了数据库一次,以下所有尝试都会导致应用程序崩溃... 我不确定是不是因为数据库没有正确发布......
例如,我运行搜索以使用艺术家名称填充tableview。一旦我选择了一位艺术家,我就会导航到一个新的桌面视图,在那里我想用艺术家的作品填充它。
但这是问题所在。我访问数据库以填充第一个视图,但是当我想填充第二个视图时,它不会输入查询的sqlite3_prepare_v2 ...所以这必须意味着旧查询仍在使用数据库..
那么在使用后处理数据库的正确方法是什么?
目前我这样做一个查询:
-(NSArray *)findAllArtists
{
NSMutableArray *returnArray = [[[NSMutableArray alloc] init] autorelease];
NSString *query = @"SELECT * FROM Painting GROUP BY Artist";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil)
== SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
char *uniqueIdChars = (char *) sqlite3_column_text(statement, 0);
char *artistChars = (char *) sqlite3_column_text(statement, 1);
NSString *uniqueId = [[NSString alloc] initWithUTF8String:uniqueIdChars];
NSString *artist = [[NSString alloc] initWithUTF8String:artistChars];
PaintingInfo *info = [[PaintingInfo alloc] initWithUniqueId:uniqueId artist:artist];
[returnArray addObject:info];
[uniqueId release];
[artist release];
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return returnArray;
}
答案 0 :(得分:4)
您应该在github上查看fmdb包装器。即使您不使用它,也请查看代码。
你在哪里打开数据库?你在这段代码中关闭了它。再次打电话之前,需要打开它。您应该考虑在单用户iOS应用程序的持续时间内保持打开状态,并在完成后关闭。如果您只是删除关闭呼叫会怎样?
您应该做的第一件事是检查sqlite调用的所有返回代码。例如,使用step,您不会处理SQLITE_ROW以外的任何内容。至少记录其他人。同样,对于最终确定和关闭,您不会处理或记录其他人。
此外,您正在准备(编译)sql语句,但您没有将其保存。 prepare_v2返回一个编译语句。将其保存为成员变量,并在再次使用之前调用reset。
要回答您关于如何结束的具体问题 - 您需要考虑某些陈述可能尚未最终确定。这是我的近距离方法:( BTW,ENDebug是我对NSLog的包装)
- (void)close
{
if (_sqlite3)
{
ENInfo(@"closing");
[self clearStatementCache];
int rc = sqlite3_close(_sqlite3);
ENDebug(@"close rc=%d", rc);
if (rc == SQLITE_BUSY)
{
ENError(@"SQLITE_BUSY: not all statements cleanly finalized");
sqlite3_stmt *stmt;
while ((stmt = sqlite3_next_stmt(_sqlite3, 0x00)) != 0)
{
ENDebug(@"finalizing stmt");
sqlite3_finalize(stmt);
}
rc = sqlite3_close(_sqlite3);
}
if (rc != SQLITE_OK)
{
ENError(@"close not OK. rc=%d", rc);
}
_sqlite3 = NULL;
}
}
最后,考虑添加更多日志记录以及返回代码,以便您获得更多洞察力。
希望有所帮助。