何时在iOS生命周期中打开和关闭SQlite数据库?

5

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

目前我正在使用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()较低,因此我认为保持数据库开放可以获得性能优势。

但是,我相信临时对象会建立起来,这可能会导致内存问题。关闭数据库可以清除临时对象。

  • 什么时候应该打开和关闭数据库连接?(例如应用程序进入后台时)
  • 在低内存情况下是否应运行VACUUM
1个回答

1

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

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

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

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

如果在收到内存警告时尝试调用VACUUM,将会导致应用程序崩溃。请考虑这一点:要重新排列数据库,它应该被加载到内存中(或者至少是其中的一部分),如果您已经收到内存警告...崩溃。

你可以测试一下你的数据库是否将对象保存在内存中。只需要每隔1秒执行大约100个查询(或按下一个按钮),并在仪表盘中观察内存增长的情况。你的应用程序可能存在泄漏问题(或包装器本身存在问题),而你却将其归咎于数据库。

谢谢你的回答。您是否百分之百确定数据库不会创建和/或保留任何对象?您可能是对的,但是文档说:“如果成功销毁sqlite3对象并释放了所有相关资源,则返回SQLITE_OK”http://www.sqlite.org/c3ref/close.html - Robert
我认为相关资源指的是连接本身,以及访问它所需的其他一些东西。就像我说的,我不确定服务器数据库是否会这样做。但是它们不需要被打开,就像我说的那样,测试它:在一个单独的类中打开数据库,执行大量查询(同时观察内存),然后关闭它。很明显会发生什么。如果它保留了某个对象,你会看到内存不断增长直到应用程序崩溃,否则一切都应该保持相对恒定的内存分配。这是最简单的方法来确保。 - skytz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接