【问题标题】:Replace Realm file while app is running在应用程序运行时替换领域文件
【发布时间】:2017-08-19 13:32:48
【问题描述】:

为了实现备份/恢复功能,我将删除现有的 Realm 数据库文件并将其替换为具有相同名称的新数据库文件。但是,由于应用程序仍在运行,它看不到新数据库文件的内容。如果我退出并重新启动应用程序,它会看到新数据库文件的内容。有什么方法可以让应用看到新内容而无需重新启动它?

【问题讨论】:

  • 澄清一下:您是说如果您在应用程序运行时替换磁盘上的 Realm 文件,您会继续看到现有数据,如果您退出然后重新启动您的应用程序,您会看到新数据?
  • 你很清楚。这是一个非常困难的问题。 T.T

标签: ios swift realm


【解决方案1】:

就像从磁盘中删除 Realm 文件一样,只有在您的应用程序当前没有打开 Realm 文件时,替换磁盘上的 Realm 文件才是安全的。

来自 Realm 在Deleting Realm files 上的文档:

因为除非绝对需要,否则 Realm 会避免将数据复制到内存中,因此 Realm 管理的所有对象都包含对磁盘上文件的引用,并且必须在文件可以安全删除之前解除分配。这包括从 Realm 读取(或添加到)的所有对象、所有 ListResultsThreadSafeReference 对象,以及 Realm 本身。

实际上,这意味着删除 Realm 文件应该在应用程序启动时在您打开 Realm 之前完成,或者仅在显式自动释放池中打开 Realm 之后完成,这样可以确保所有 Realm 对象都已被删除。已解除分配。

这样做的原因是 Realm 维护一个打开文件的内存缓存,因此尝试打开已经打开的文件将导致返回对已打开文件的引用。这个打开的文件将继续引用磁盘上的原始文件,即使它已被替换。确保对 Realm 访问器对象的所有引用都已被清除意味着 Realm 将不会返回现有的打开文件,而是会从磁盘打开文件。

换句话说,当您尝试替换 Realm 文件时,您必须确保没有引用 Realm 的访问器对象(RealmResultsThreadSafeReferenceObject 实例)。您还必须确保您执行的所有引用都已被释放(即,它们没有在调度队列的默认自动释放池中徘徊)。

另一种可能更易于管理的方法是在您尝试重新打开恢复的文件时使用不同的路径。由于您正在访问磁盘上的不同路径,因此可以保证打开新文件。你仍然需要确保你没有对 Realm 的访问器对象的引用,否则你会得到新旧数据的奇怪混合,但确保访问器对象被释放并不那么重要。

【讨论】:

  • 我阅读了答案。我最容易理解的方法是将新文件移动到新路径,然后将新路径设置为 defaultConfiguration。
  • 是的,这就是我所说的替代方法的意思。
  • 我选择它。 -> “我描述的替代方法”
  • 您的回答帮了大忙。非常感谢。
  • @SwiftStarter - 我一直在尝试替换从 iCloud 下载的领域文件,将其替换在原始领域文件所在的位置 - 在添加新文件之前,我还从该位置下载了每个文件但在我杀死它并重新运行应用程序之前,仍然无法获取应用程序上的数据。重新运行后开始获取新记录 - 如果您找到任何解决方案,请帮助我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
相关资源
最近更新 更多