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

标签 ios sqlite

我有一个应用程序,我多次访问 SQLite 数据库。但是,一旦我访问了数据库一次,接下来的所有尝试都会导致应用程序崩溃...... 不知道是不是因为数据库没有正常发布...

例如,我运行搜索以使用艺术家姓名填充表格 View 。选择一位艺术家后,我将导航到一个新的表格 View ,我想在其中填充该艺术家的作品。

但是问题来了。我访问数据库以填充第一个 View ,但是当我想填充第二个 View 时,它不会输入查询的 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;    
}

最佳答案

你应该看看 github 上的 fmdb wrapper。即使您不使用它,也请查看代码。

你在哪里打开数据库?您将在此代码中关闭它。在您再次调用它之前,它需要打开。您应该考虑在单用户 iOS 应用程序运行期间保持打开状态,并在完成后关闭。如果您简单地删除 close call 会发生什么?

您应该做的第一件事是检查 sqlite 调用的所有返回码。例如,对于 step,除了 SQLITE_ROW 之外,您不处理任何其他内容。至少记录其他人。此外,对于完成和关闭,您不会处理或记录其他人。

此外,您正在准备(编译)sql 语句但没有保存它。 prepare_v2 返回编译后的语句。将其保存为成员变量并在再次使用之前对其调用 reset。

要回答您关于如何关闭的具体问题 - 您需要考虑到某些报表可能尚未最终确定。这是我的关闭方法:(顺便说一句,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;
    }
}

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

希望对您有所帮助。

关于iOS:多个查询导致应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7683193/

相关文章:

iOS Map Kit Locations 从数据库读取

objective-c - UIGestureRecognizer State Changed 和 touchesMoved 之间有什么区别?

c++ - 如何在网络共享驱动器上使用 sqlite3 数据库?

python - 类型错误 : 'NoneType' object has no attribute '__getitem__' in Flask using SQLite3

ios - 使用字典将 NSString 中的多个字符替换为多个其他字符

ios - 你如何找出一个对象的类型

ios - iOS8 中的表格 View 单元自动布局

sql - 返回值进行比较

android - 如何在子 Activity 返回时更新父 Activity 的 ListView

java.sql.SQLException : no such column and false Period getDays result