我使用 NSPersistentStoreCoordinator 创建了一个文件,但在应用重启后找不到它

I create a file using NSPersistentStoreCoordinator, but it's not found after app restart

我正在尝试 backup/restore 我的核心数据存储;在我的应用程序中,我创建了文件,执行 fileExistsAtPath 并且文件就在那里。当我使用 Finder 时,它不存在。这是创建备份的代码(我复制并修改过,所以样式和重复命名不是我的;可能应该重新开始):

更新代码是here...

这是控制台输出:

currentURL is file:///Users/spokanedude/Library/Developer/CoreSimulator/Devices/1EE69744-255A-45CD-88F1-63FEAD117B32/data/Containers/Data/Application/41B5E165-C3E2-4D8A-81EB-98ADB20B8B0D/Documents/saori.sqlite 2015-01-20 10:41:36.042 SalonBook[84743:2055509]

backup file URL to use is file:///Users/spokanedude/Library/Developer/CoreSimulator/Devices/1EE69744-255A-45CD-88F1-63FEAD117B32/data/Containers/Data/Application/41B5E165-C3E2-4D8A-81EB-98ADB20B8B0D/Documents/saori.backup-20153920103944

2015-01-20 10:41:36.042 SalonBook[84743:2055509]

currentCoreData exists 2015-01-20 10:41:36.042 SalonBook[84743:2055509]

backupFile exists 2015-01-20 10:41:36.042 SalonBook[84743:2055509]

target file exists 2015-01-20 10:41:36.092 SalonBook[84743:2055509] current store file removed

2015-01-20 10:41:36.125 SalonBook[84743:2055509] replaced current store file successfully

2015-01-20 10:41:36.126 SalonBook[84743:2055509] store Options are { NSSQLitePragmasOption = { "journal_mode" = WAL; }; } 2015-01-20 10:41:36.127 SalonBook[84743:2055509] addPersistentStoreWithType completed successfully...

2015-01-20 10:41:36.127 SalonBook[84743:2055509] STORE FILE is /Users/spokanedude/Library/Developer/CoreSimulator/Devices/1EE69744-255A-45CD-88F1-63FEAD117B32/data/Containers/Data/Application/41B5E165-C3E2-4D8A-81EB-98ADB20B8B0D/Documents/saori.sqlite

当我做备份时,它说文件在那里;当我使用 ForkLift(Finder 替代品)时,它会出现(有时);当我进行恢复时,它找到了文件并说恢复成功,但它却清除了现有数据,就像文件内容丢失一样。我这辈子都弄不明白...不胜感激。

首先,查看fileExistsAtPath:的文档。您将看到此警告:

Attempting to predicate behavior based on the current state of the file system or a particular file on the file system is not recommended. Doing so can cause odd behavior or race conditions. It’s far better to attempt an operation (such as loading a file or creating a directory), check for errors, and handle those errors gracefully than it is to try to figure out ahead of time whether the operation will succeed.

这正是您正在做的,并且您看到了意外行为。

当使用 WAL 模式时,您需要的大部分数据不在 "saori.sqlite" 文件中,而是在 SQLite 将放置在同一目录中的其他文件中。使用 WAL 模式时,"saori.sqlite" 文件实际上可能永远不会被写入。 Apple Technical QA 1809 documents this, and there is more detail available in the SQLite documentation.

出于这个和其他原因,给每个 Core Data SQLite 存储它自己的目录通常是个好主意。

如果您尝试将 "saori.sqlite" 文件复制到新位置并使用 Core Data 不使用 打开它,则存储的其他文件实际上将是空的。你会去:(

不幸的是,这就是您的恢复实施所做的。它获取备份 "saori.sqlite" 文件并将其复制到一个新位置,而没有 WAL 模式使用的其他文件。然后它使用该位置添加一个新存储 - 但是缺少 WAL 文件,因此 Core Data 创建新的。这会导致数据丢失 - 您的数据从未移动过,而 Core Data 创建了新文件。

推荐的恢复方式与备份相反:使用迁移。