我有一个基于核心数据的应用程序,它使用Dropbox备份和恢复数据。我备份的方式非常简单。我将.sqlite文件复制到用户的保管箱上。
现在我的备份和恢复功能正常。问题出在.sqlite文件本身。看来.sqlite文件不完整。
我在我的应用程序中输入了大约125个条目并进行了备份。备份出现在我的Dropbox中,但当我使用.sqlite资源管理器工具查看内容时,我只看到第117个记录的记录。
我尝试更新第一个条目,然后再次观察.sqlite文件,但没有再次更改。
更奇怪的是该应用程序似乎记录了所有更改。当我添加新条目或更新现有条目并重新启动应用程序时,新添加的数据似乎仍然存在。 但是这个新添加的数据不会出现在我的.sqlite文件中。
我正在使用此代码备份:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSString *filePath = [[[appDelegate applicationDocumentsDirectory] path] stringByAppendingPathComponent:@"MyApp.sqlite"];
if (account) {
if ([filesystem isShutDown]) {
filesystem = [[DBFilesystem alloc] initWithAccount:account];
[DBFilesystem setSharedFilesystem:filesystem];
}
DBPath *newPath = [[DBPath root] childPath:[NSString stringWithFormat:@"Backup - %@.sqlite", [NSDate date]]];
DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil];
[file writeContentsOfFile:filePath shouldSteal:NO error:nil];
[filesystem shutDown];
}
我还从Simulator的文件夹中复制了.sqlite文件,并尝试在.sqlite浏览器中看到它。它仍然表现出相同的行为。有必要发生这种情况的原因吗?
答案 0 :(得分:6)
从iOS 7 / OS X 10.9开始,核心数据使用"预写日志记录" (WAL)默认 基础SQLite存储文件的日记模式。
中对此进行了解释使用WAL模式,Core Data保持主存储文件不受影响 将事务附加到同一位置的-wal文件。之后 保存核心数据上下文,不删除-wal文件和数据 在该文件中也没有合并到商店文件。因此,简单地说 制作商店文件的副本可能会导致数据丢失 不一致性。
这应该解释为什么单独的.sqlite文件不完整。 作为解决方案,你可以(也在技术说明中解释):
通过设置
为SQLite存储禁用WAL模式(并使用"旧"回滚日记模式)@{NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}};
添加持久存储时的选项,或
使用
- (NSPersistentStore *)migratePersistentStore:(NSPersistentStore *)store toURL:(NSURL *)URL options:(NSDictionary *)options withType:(NSString *)storeType error:(NSError **)error
制作Core Data商店备份副本的方法。