正确的领域使用模式/最佳做法?


76

我们正在将项目转换为使用Realm。到目前为止,特别是对于Realm Browser来说,我们印象深刻(非常方便!)。

结果,出现了一些问题,我们希望在继续进行之前先弄清一些具体的使用模式。我们的应用程序具有大量的多线程(API调用,动画等),因此在阅读问题时请记住这一点,因为我知道Realm实例无法(当前)跨线程访问。

  • 我们应该如何担心重复创建Realm实例?开销是多少?
  • 我们是否应该在ViewControllers或Singletons中保留Realm实例以便重复使用?我们已经尝试过了,但是有时实例是从不同的线程访问的,因此我们不得不每次都恢复为创建新实例。
  • 在Realm实例上访问关系属性时,读取的结果数据是保留在内存中还是每次都从磁盘读取?我们是否需要担心由于深层关系访问而导致保留的Realm实例太大?
  • 什么时候需要刷新Realm实例?我注意到,当我在Realm浏览器中进行更改时,它们会反映在保留的Realm中,而无需调用refresh。
    • 根据文档,每个域上似乎都有一个导致该问题的自动刷新属性。
  • 是否出于不当行为而使用该realm财产Object?如果使用对象的函数未创建对象或领域(当然是在同一线程上),则我们已将其用于写入领域。

例如...

func saveStuff(thingToUpdate: Object?) {
   if let thingToUpdate = thingToUpdate, let realm = thingToUpdate.realm {
       realm.write {
           thingToUpdate.name = "lionpants"
       }
   }    
}

提前致谢。期待您的答复。:D

Answers:


85

(免责声明: 我为Realm工作。我现在已经离开了Realm,但我仍然很乐意为您提供帮助!):)非常 感谢!很高兴听到您喜欢Realm!

多个领域实例-您完全无需担心!在每个线程上第一次实例化时都会创建一个Realm文件对象,并且每次尝试并在之后每次实例化该对象时,都会返回该对象。

保留Realm实例-从第一点开始,不,您不必担心要挂在其他对象内部的Realm引用。由于Realm在内部跟踪其Realm文件对象并返回相同的对象,因此您不会因未这样做而受到惩罚。话虽如此,如果在对象内部永久引用Realm对象简化了代码复杂度,请随时使用它。

访问Realm关系属性-严格来说,不是从磁盘复制Realm文件中的数据(就像普通的ORM那样)。此外,它还使用内存映射直接将磁盘中的数据直接引用到您的内存中属性。因此,不,您不必担心Realm文件的内存过大。

自动刷新 默认情况下,仅对主线程上的Realm文件对象启用自动刷新。必须为其他线程上的Realm文件对象手动启用它,或者您可以选择使用refresh方法调用手动刷新它们。

编辑:我站纠正!autorefresh默认情况下,多个线程上的所有Realm文件对象均处于启用状态。如果autorefresh是,你需要调用唯一的一次refresh是,如果你需要体现在其他文献的运行循环的当前迭代完成之前到领域文件所做的更改。

引用对象的Realm引用 绝对不是,这不是一个坏习惯!我实际上更喜欢在使用Realm的个人应用程序中执行此操作,以提供适当的上下文,因为它总是更容易,并且在对象及其代码中的父Realm文件之间提供了更强的可视上下文。(是的,如果这里有线程问题,您甚至可能在发现问题之前就已经发现了write)。


希望对您有所帮助!让我知道您是否需要在这里澄清任何内容!


太棒了!感谢您的超快速响应。我们将在问题弹出时再发布更多问题!关于自动刷新仅在默认情况下在主线程上默认启用的要点也应该添加到文档中。:)
lionpants

4
一点也不!非常感谢!啊,实际上我已经纠正了。我只是回过头来检查代码以确认这一点,现在看来默认情况下所有线程都启用了自动刷新。我已经更新了我的答案以反映这一点。
TiM

这个问题确实让我感到非常压力,我似乎
无法解决

对于iOS?您可以在Realm GitHub存储库中使用更多信息来创建有关此问题的信息吗?github.com/realm/realm-cocoa
TiM
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.