如何在 applicationDidEnterBackground 上保存 SQL 数据/关闭 DB 并在 applicationWillEnterForeground 上恢复

Posted

技术标签:

【中文标题】如何在 applicationDidEnterBackground 上保存 SQL 数据/关闭 DB 并在 applicationWillEnterForeground 上恢复【英文标题】:How to save SQL Data/Close DB on applicationDidEnterBackground and resume on applicationWillEnterForeground 【发布时间】:2011-05-23 22:06:11 【问题描述】:

我有一个打开了 4 或 5 个 SQL 表的应用程序。

当用户点击主页按钮并调用 applicationDidEnterBackground 时,我将所有脏记录保存到表中:

[self.shoppingListArray makeObjectsPerformSelector:@selector(saveAllData)];

...

- (void)saveAllData 
    if(isDirty) 
        if(updateStmt == nil)  
            const char *sql = "UPDATE ShoppingList SET Section = ?, Question = ?, Checked = ?, Modified = ? WHERE ID = ?";
            if(sqlite3_prepare_v2(database, sql, -1, &updateStmt, NULL) != SQLITE_OK)
                NSAssert1(0, @"Error while creating update statement. '%s'", sqlite3_errmsg(database));
        

        NSLog(@"DIRTY Item Was Updated: %@", Question);

        sqlite3_bind_text(updateStmt, 1, [Section UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(updateStmt, 2, [Question UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(updateStmt, 3, isChecked ? [@"YES" UTF8String]:[@"NO" UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(updateStmt, 4, isModified ? [@"YES" UTF8String]:[@"NO" UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_int(updateStmt,  5, ID);

        if(SQLITE_DONE != sqlite3_step(updateStmt))
            NSAssert1(0, @"Error while updating. '%s'", sqlite3_errmsg(database));

        sqlite3_reset(updateStmt);

        isDirty = NO;
    
    //Reclaim all memory here.
    [Section release];
    Section = nil;
    [Question release];
    Question = nil;
    isDetailViewHydrated = NO;

然后我完成语句并关闭数据库:

[ShoppingListInformation finalizeStatements];

...

+ (void) finalizeStatements 
    if(database) sqlite3_close(database);
    if(deleteStmt) sqlite3_finalize(deleteStmt);
    if(updateStmt) sqlite3_finalize(updateStmt);
    if(addStmt) sqlite3_finalize(addStmt);

那么,问题是调用 applicationWillEnterForeground 时我该怎么办?

我是否重新打开数据库并重新填充我的数组并重新加载表视图?

在不丢失用户数据、恢复状态等的情况下,解决此问题的最佳做法是什么?

任何帮助表示赞赏!

【问题讨论】:

只有受虐狂直接在 Objective-C 中使用 SQLite C API。 Use FMDB(SQLite 包装器)或CoreData(对象图管理器)。 哈!我听说过 FMDB,所以我应该对此进行更多研究。我听其他用户评论说,如果你不知道自己在用 CoreData 做什么,你真的会把自己弄得一团糟吗? 【参考方案1】:

我建议不要关闭数据库或完成语句,除非应用程序正在关闭 (applicationWillTerminate:)。然后,您将以离开时的状态返回应用程序,无需任何操作。我不确定这是最有效的方法,但它对我有用。

【讨论】:

这就是我一直在做的事情,但我担心用户会丢失数据。如果用户在应用程序暂停时硬重置手机怎么办?我不确定,但我认为 applicationWillTerminate 在这种情况下不会触发,这可能会导致数据丢失?我想我可以在设备上测试它。不过还是感谢您的意见! 您不必关闭数据库或完成语句即可将数据保存到数据库。当你进入后台时,你仍然会调用 saveAllData。 好的,deepmist 有帮助!谢谢!

以上是关于如何在 applicationDidEnterBackground 上保存 SQL 数据/关闭 DB 并在 applicationWillEnterForeground 上恢复的主要内容,如果未能解决你的问题,请参考以下文章

在QGIS中如何添加天地图的WMTS

如何在表单提交后保留文本(如何在提交后不删除自身?)

如何在异步任务中调用意图?或者如何在 onPostExecute 中开始新的活动?

在 Avkit 中如何使用这三行代码,以及如何将音乐静音”

如何在 JDBC 中启动事务?

如何在 Fragment 中调用 OnActivityResult 以及它是如何工作的?