iOS:多个查询崩溃应用程序

时间:2011-10-07 04:53:27

标签: ios sqlite

我有一个应用程序,我多次访问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;    
}

1 个答案:

答案 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;
    }
}

最后,考虑添加更多日志记录以及返回代码,以便您获得更多洞察力。

希望有所帮助。