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

Posted

技术标签:

【中文标题】我使用 NSPersistentStoreCoordinator 创建了一个文件,但在应用重启后找不到它【英文标题】:I create a file using NSPersistentStoreCoordinator, but it's not found after app restart 【发布时间】:2015-01-20 19:02:03 【问题描述】:

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

更新代码是here...

这是控制台输出:

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

要使用的备份文件 URL 是 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 存在 2015-01-20 10:41:36.042 SalonBook[84743:2055509]

备份文件存在 2015-01-20 10:41:36.042 SalonBook[84743:2055509]

目标文件存在 2015-01-20 10:41:36.092 SalonBook[84743:2055509] 当前商店文件已删除

2015-01-20 10:41:36.125 SalonBook[84743:2055509] 成功替换当前商店文件

2015-01-20 10:41:36.126 SalonBook[84743:2055509] 商店选项是 NSSQLitePragmasOption = “journal_mode”=WAL; ; 2015-01-20 10:41:36.127 SalonBook[84743:2055509] addPersistentStoreWithType 成功完成...

2015-01-20 10:41:36.127 SalonBook[84743:2055509] 存储文件是 /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 替代品)时,它会出现(有时);当我进行还原时,它会找到文件并说还原成功,但它会清除现有数据,就像文件内容丢失一样。我这辈子都想不通...帮助将不胜感激。

【问题讨论】:

该控制台输出与代码 sn-p 中的 NSLog 调用完全不同。运行代码有什么收获? 我没有将代码用于恢复...有问题的控制台输出来自那里...我讨厌放那么多代码... pastebin 可以吗? 您应该包含与问题相关的任何代码。控制台输出应与问题中包含的代码匹配。 给你...pastebin.com/zEifXizv 【参考方案1】:

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

不建议尝试基于文件系统的当前状态或文件系统上的特定文件来判断行为。这样做可能会导致奇怪的行为或竞争条件。尝试操作(例如加载文件或创建目录)、检查错误并优雅地处理这些错误比尝试提前确定操作是否成功要好得多。

这正是你正在做的事情,你看到了意想不到的行为。

当使用 WAL 模式时,您想要的大部分数据不在“saori.sqlite”文件中,而是在 SQLite 将放置在同一目录中的其他文件中。使用 WAL 模式时,实际上可能永远不会写入“saori.sqlite”文件。 Apple Technical QA 1809 记录了这一点,SQLite documentation 中提供了更多详细信息。

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

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

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

执行还原的推荐方法与备份相反:使用迁移。

【讨论】:

我想将备份存储在用户的 Documents 目录中,因为我认为这是推荐的。我只有一个 CD 存储(saori.sqlite)...当我查看 ForkLift 中的目录时,它们似乎在那里,并且所有三个文件(saori.backup、shm 和 wal 都在那里)。我可以使用 SQLite Professional 打开备份文件,但这不是恢复的内容! "我可以使用 SQLite Professional 打开备份文件,但这不是恢复的内容!" 什么意思?恢复什么?是否缺少数据(尤其是关系)? SQLite Prof 在文件复制之前或之后显示它?我建议改用 Core Dara Editor 等特定于 Core Data 的工具。 SQLite 工具经常对正在发生的事情显示出误导性的画面:您可能只看到 .sqlite 文件中的内容很少,并认为所有数据都在那里,而实际上您想要的数据在其他(丢失的)文件中。专注于 CoreData 的工具不太可能有同样的问题。

以上是关于我使用 NSPersistentStoreCoordinator 创建了一个文件,但在应用重启后找不到它的主要内容,如果未能解决你的问题,请参考以下文章

如果我从多个线程中使用 JSch,我应该如何使用它

访问我加载的 .pdf 页面(使用 pdfbox)(我正在使用 RPG)

如何使用 AFNetworking 框架与 json 一起使用我自己的 api 登录我有令牌要传递但我现在不知道如何使用这些

尝试使用嵌套对象数据循环遍历对象,并使用我卡中的数据进行渲染

为啥我不应该使用 Unity?

如果我想通过 Annotation 使用 hibernate,我必须使用 javax.persistence.* 吗?