【发布时间】:2014-05-02 15:55:19
【问题描述】:
我在使用 SQLite 数据库损坏的应用时遇到问题。以前有这种奇怪的情况,但在 iOS 7.1 发布后似乎变得更加普遍。
我正在使用 Matteo Bertozzi 的 SQLite 包装器,您可以在此处找到:https://github.com/ConnorD/simple-sqlite
数据库损坏并吐出错误database disk image is malformed,可以运行一些查询但现有数据被弄乱了。
我已经搜索了高和低,但找不到解决方案,我希望这里的人有一些想法,因为这在 iOS 更新后成为一个更常见的问题。
我试过这些修复命令:
[sqlite executeNonQuery:@"pragma integrity_check"];
[sqlite executeNonQuery:@"reindex nodes"];
[sqlite executeNonQuery:@"reindex pristine"];
输出是:
SQLite Step Failed: database disk image is malformed
SQLite Prepare Failed: unable to identify the object to be reindexed
- Query: reindex nodes
SQLite Prepare Failed: unable to identify the object to be reindexed
- Query: reindex pristine`
经过进一步挖掘,我发现了这个问题:Core Data and iOS 7: Different behavior of persistent store,其中提到了 iOS7 之后的 SQLite 问题。
虽然我不知道如何使用NSPersistentStore,所以我尝试运行[sqlite executeNonQuery:@"pragma journal_mode = DELETE"];,它只是说SQLite Step Failed: unknown error。
有没有其他人遇到过这种情况,或者指出我正确的方向?
与此同时,我觉得 NSPersistentStore 是我可能应该做的事情.. 必须对此进行调查。
编辑:
据我发现,您只在数据库不更新时才使用NSPersistentStore,而我的数据库是定期更新的。
这是我打开数据库的方法:
sqlite = [[Sqlite alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"HomeOpenDatabase8.sql"];
if (![sqlite open:writableDBPath]) {
NSLog(@"DB Not Writable");
return;
} else {
NSLog(@"All good");
}
所以我假设我需要找到一种方法来设置pragma journal_mode = DELETE 这种方式..?
编辑 2:
我不相信这与 journal_mode 有关,因为我没有使用 Core Data - 回到绘图板。
对我来说最大的问题是这个错误在 iOs 7.1 发布后不久就出现了,这肯定不是巧合。我会继续尝试在我的设备上复制这个问题。
【问题讨论】:
-
您是否可以执行某些步骤来可靠地重现损坏?
-
我自己无法复制它,这是一个巨大的痛苦,但我会继续尝试。我不再相信它是
journal_mode,因为我没有使用Core Data,所以它又回到了原点。 -
你为什么要搞乱编译指示?
-
我猜你不小心开始以多线程模式访问数据库。即使在“线程安全”的情况下,SQLite 实际上也无法处理完整的多线程——您至少必须提供外部同步以确保两个线程不会同时在数据库上运行。据我所知,所有“线程安全”所做的都是启用检查,如果您尝试同时访问,通常会抛出错误。
-
你是对的。我为我的数据库服务添加了锁定,以仅通过一个线程访问 SQLite DB,它现在可以工作了。
标签: ios objective-c sqlite wrapper ios7.1