【问题标题】:SQLite Persistence project : errorMsgSQLite 持久性项目:errorMsg
【发布时间】:2013-06-24 05:32:42
【问题描述】:

我在我的 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 Persistence[5373:c07] 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“更新表时出错:(null) “**第一掷调用堆栈:(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)

【问题讨论】:

  • LPEViewController.m 文件中的第 84 行是哪一行?
  • else 语句添加到第一个if 语句并记录错误以防prepare 语句失败。
  • update 的值是多少? i 的?文本字段的?
  • 你从未设置过errorMsg。您需要调用sqlite3_errmsg 并将其分配给errorMsg
  • 你陷入了断言,因为你得到了一个错误的返回码。崩溃是 NSAssert 所做的。 sqlite3_step 的返回码可能不是 SQLITE_DONE 的原因有很多,其中一些是“正常的”。

标签: ios sqlite ios5


【解决方案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 失败情况并报告有意义的错误。

【讨论】:

  • @arun - 对于它的价值,我通常建议人们查看FMDB。它是一个瘦包装器,但也大大简化了 SQLite 代码的编写。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-04
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 2018-11-11
  • 1970-01-01
相关资源
最近更新 更多