1

我在我的 NSAssert 中使用 errorMsg,但我只将其定义为 NULL,从未使用它来获取实际的错误消息。因此,它将始终为 NULL,并且没有必要在 NSAssert 中使用它。

<...>

char *errorMsg = NULL;


    sqlite3_stmt *stmt;

    if (sqlite3_prepare_v2(database, update, -1, &stmt, nil)

        == SQLITE_OK) {

        sqlite3_bind_int(stmt, 1, i);

        sqlite3_bind_text(stmt, 2, [field.text UTF8String], -1, NULL);

    }

    if (sqlite3_step(stmt) != SQLITE_DONE)

        NSAssert(0, @"Error updating table: %s", errorMsg);

<...>

有人会给出解决方案吗?当我运行该应用程序时,没有任何伤害。但是,当我按下主页按钮时,该过程暂停并向我显示:

2013-05-20 23:57:50.156 SQLite Persistence[5373:c07] * -[LPEViewController applicationWillResignActive:] 中的断言失败,/Users/Me/Developer/SQLite Persistence/SQLite Persistence/LPEViewController.m:84 2013-05- 20 23:57:50.158 SQLite 持久性 [5373:c07]Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error updating table: (null)' * * First throw call stack: (0x2094012 0x11a1e7e 0x2093e78 0xc37665 0x3c09 0xc624f9 0x20ee0c5 0x2048efa 0xb96bb2 0xe2bb1 0xe2c3d 0xece0c 0xf5e74 0xf6beb 0xe8698 0x1fefdf9 0x1fefad0 0x2009bf5 0x2009962 0x203abb6 0x2039f44 0x2039e1b 0x1fee7e3 0x1fee668 0xe5ffc 0x2b4d 0x2a75) libc++abi.dylib:终止调用抛出异常 (lldb)

4

1 回答 1

1

几个问题:

  1. 你从来没有设置errorMsg. 确保将其设置为sqlite3_errmsg(或直接使用该功能)。

  2. 您的自定义错误消息(“错误更新表”)也有点误导,因为它暗示您正在报告表的名称,而您选择的变量名称表明您确实想要报告 SQLite 错误消息。

  3. 如果sqlite3_prepare_v2失败,您不会报告任何错误消息。此外,如果失败,您不会停止并报告错误sqlite3_prepare_v2,而是继续尝试调用sqlite3_step,即使没有要执行的有效语句。这样做的问题是,它无疑会sqlite3_prepare_v2用一些关于以错误顺序执行语句的无用消息来代替您在失败后收到的有意义的错误消息。

  4. 你不检查你的sqlite3_bind陈述的成功或失败。这样做是谨慎的(尽管我怀疑你更有可能在sqlite3_prepare_v2声明中失败)。

无论如何,也许你想要类似的东西:

sqlite3_stmt *stmt;

if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) != SQLITE_OK)
    NSAssert(0, @"prepare failure: %s", sqlite3_errmsg(database));

if (sqlite3_bind_int(stmt, 1, i) != SQLITE_OK) {
    sqlite3_finalize(stmt);
    NSAssert(0, @"bind 1 failure: %s", sqlite3_errmsg(database));
}

if (sqlite3_bind_text(stmt, 2, [field.text UTF8String], -1, NULL) != SQLITE_OK) {
    sqlite3_finalize(stmt);
    NSAssert(0, @"bind 2 failure: %s", sqlite3_errmsg(database));

if (sqlite3_step(stmt) != SQLITE_DONE) {
    sqlite3_finalize(stmt);
    NSAssert(@"step error: %s", sqlite3_errmsg(database));
}

sqlite3_finalize(stmt);

无论您是想使用NSAssert还是NSLog直接返回,我都会听从您的安排,但此代码示例将检查更多 SQLite 失败情况并报告有意义的错误。

于 2013-06-27T01:32:50.843 回答