【问题标题】:When to open and close a SQlite DB in the iOS lifecycle?在 iOS 生命周期中何时打开和关闭 SQlite DB?
【发布时间】:2013-05-21 14:15:12
【问题描述】:

我在应用程序的整个生命周期中运行了一系列查询。

我目前正在使用FMDB(一个围绕 Sqlite C API 的 Objective-C 包装器),并且在每次查询之前我都会打开和关闭。

FMDatabase * db = [FMDatabase databaseWithPath:pathToMyDB];
[db open]
FMResultSet * s = [db executeQuery:@"SELECT * FROM myTable"];
// Use FMResultSet
[db close];

打开和关闭触发器fopen()fclose() 较低,所以我相信我可以通过保持数据库打开来获得perforce 胜利。

但是,我相信临时对象会堆积起来,这可能会导致内存问题。 Closing the database 清除临时对象。

  • 我应该何时打开和关闭数据库连接? (例如,应用程序确实进入了后台?)
  • 我应该在内存不足的情况下运行 VACUUM 吗?

【问题讨论】:

    标签: ios cocoa-touch sqlite memory-management


    【解决方案1】:

    数据库不创建和/或保留任何对象(或至少不应该)。 C API 只是一种使用 SQL 查询的便捷方式,但一旦执行这些查询,它们就应该被释放。

    现在,对于查询的返回对象,它们只是被复制到您的 FMResultSet 中。一旦你释放它们就消失了。

    Imo,如果数据库本身不是太大,您应该在您的应用程序委托中保留对它的引用(保证在您的应用程序的生命周期内保持活动状态)。当您从后台进入应用程序/简历时,打开数据库,当您进入后台/关闭时,只需将其关闭。

    请记住,AppDelegate 是一个单例(我认为),您可以在应用程序的任何位置使用 (AppDelegate*)[[UIApplication sharedApplication]delegate].your_db 访问您的数据库以执行实际查询。

    如果您在收到内存警告时尝试调用 VACUUM,则使用 VACUUM 会使您的应用程序崩溃。想一想:要重新排列数据库,它应该被加载到内存中(或者至少是其中的一部分),如果你已经有内存警告......噗......崩溃。

    您可以测试您的数据库是否将对象保存在内存中。只需以 1 秒的间隔(或按一下按钮)执行 100 次查询,然后在仪器中观察内存在何处以及是否增长。您的应用程序(或包装器本身)可能存在泄漏,并将其归咎于数据库。

    【讨论】:

    • 感谢您的回答。您是否 100% 确定数据库不会创建和/或保留任何对象?你可能是对的,但是,这个文档说:“如果 sqlite3 对象被成功销毁 并且所有相关资源都被释放,则返回 SQLITE_OK”sqlite.org/c3ref/close.html
    • 我认为关联资源是指连接本身,以及您需要访问它的其他一些东西。正如我所说,我不确定,服务器数据库会这样做。然后再一次,它们本身不需要打开。照我说的做,像这样测试它:在一个单独的类打开数据库中,执行大量的查询(同时观察内存)然后关闭它。发生的事情应该很明显。如果它保留了一些对象,你会看到内存一直在增长,直到应用程序崩溃,如果不是所有的东西都应该保持相对恒定的内存分配。这是最简单的确定方法。
    猜你喜欢
    • 2011-03-25
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 2017-11-28
    • 2016-05-12
    • 1970-01-01
    相关资源
    最近更新 更多