我在使用SQLite作为数据库后端的iPhone SDK上的新应用程序出现问题。
有时,我的应用程序将停止将数据加载到我的UITableViews,并在通过管理器下载设备数据库后,我可以通过命令行访问SQLite DB。我可以查询某些表,但没有得到“SQL错误:数据库磁盘映像格式错误”错误。请参阅下面的sqlite会话:
SQLite version 3.6.17
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from user;
1|cpjolicoeur@gmail.com|cpjolicoeur||4d055e38bb1d3758|image/gif|cartoonme_avatar.gif||Craig|Jolicoeur|1|1
sqlite> select * from item;
SQL error: database disk image is malformed
sqlite>
在这个示例中,我的用户表工作正常,但我的项目表格格式错误,这与我在我的应用程序中看到的项目不相关的内容相对应。该应用程序没有崩溃,数据只是因为这个格式错误而无法加载。
为什么会发生这种情况?我唯一的想法是,数据库可能已损坏,因为我通过应用程序中的后台线程写入SQLite数据库。我通过后台线程中的NSOperationQueue从Web服务器下载数据,并使用下载的数据更新SQLite DB。在后台线程中写入数据库(虽然可能从主线程中读取)会破坏数据库,还是其他东西?
答案 0 :(得分:5)
在调试时,您必须非常小心后台线程访问数据库!这是因为当调试器暂停处理(例如在断点处)时,所有线程都会暂停,包括可能位于数据库调用中间的线程,介于数据库“open”和数据库“close”调用之间。 / p>
如果您在断点处停止,并单击Xcode中的停止标志,您的应用会立即退出。这通常会导致错误,例如您看到的错误或“损坏的数据库”错误。
确实没有任何解决方案(因为没有办法修改“停止任务”的行为,但我已经发展了一些技术来缓解它: 1.添加代码以检测进入后台的应用程序并正常停止数据库操作。 2.调试时切勿使用停止标志停止处理。相反,当使用断点然后“继续”时,点击模拟器或设备上的主页按钮(应触发您在步骤1中添加的代码),等待应用程序返回后台,然后您可以停止运行。
答案 1 :(得分:5)
在我的情况下,这与iOS 7有关:在iOS 7上,Core Data现在使用SQLite WAL日记模式,该模式将数据写入.db-wal
文件,而不是直接写入.db
文件。在我的应用中,我会在应用更新期间将准备好的.db
文件复制到Library/Application Support
。问题是旧的.db-wal
文件仍在该目录中,我只替换了.db
文件。这样,我最终得到的.db
文件与旧的.db-wal
文件不同步。
这个问题有两种解决方案:
.db
文件复制到位之前,请确保删除.db-wal
,.db-shm
和.db
个文件。答案 2 :(得分:0)
取决于如何编译SQLite,它可能是也可能不是线程安全的。如果你使用的是内置的,它可能没有你正在寻找的编译时选项。
对于我们的应用,我们必须推出自己的SQLite来添加全文搜索。看看this page。