考虑以下RealmObject子类

public class TimeSlot extends RealmObject
{
 @PrimaryKey
 private int value = 0;
 private int hits = 0;

 @LinkingObjects("ats") private final RealmResults<Visit> visits = null;

 public TimeSlot(){}

 public TimeSlot(int time)
 {
  super();
  value = time;
 }

  ...
}

public class Visit extends RealmObject
{
 private RealmList<TimeSlot> timeslots = null;

 public Visit()
 {
  super();
  timeslots = new RealmList<TimeSlot>();
 }

 public void addTimeSlot(TimeSlot ts) throws Exception
 {
  this.timeslots.add(ts);
  try
  {
   myRealm.beginTransaction();
   myRealm.copyToRealmOrUpdate(this,ImportFlag.valueOf("CheckSameValuesBeforeSet"));
   myRealm.commitTransaction();
  }
  catch(Exception e)
  {
   myRealm.cancelTransaction();
   throw e;
  }
 }
}


我在代码的其他地方执行以下操作

myVisit.addTimeSlot(new TimeSlot(30));


向访问对象TimeSlot的现有实例添加新的myVisit。您会注意到,在addTimeSlot中,我将修改后的Visit实例复制到Realm。我的问题-这样做还会保留新创建的TimeSlot对象吗?

一个相关的问题-当我从Realm中检索myVisit时,是否可以保证myVisit.timeslots中的TimeSlot对象与添加它们时的顺序相同?

最佳答案

如果您知道在哪里查看,大多数问题都会在Realm文档中回答。主要文档中提示了许多这些问题,然后您需要找到正确的API页面。有时只能尝试一下。


  您会注意到,在addTimeSlot中,我将修改后的Visit实例复制到Realm。我的问题-这样做还会保留新创建的TimeSlot对象吗?


那是对的。 copyToRealmOrUpdate的文档状态:“这是深层副本或更新,即所有引用的对象都将被复制或更新。”

您已经介绍了一个潜在的问题。 addTimeSlot的第一行立即修改Visit对象。如果Visit对象不受管理,或者在addTimeSlot调用之外启动了Realm事务,这很好。但是,如果不是这种情况,那么您将收到有关“尝试在写事务之外修改对象”的异常。您的方法依赖于您始终对对象的非托管版本进行操作,并将每个更改手动复制回Realm。实际上,这不是推荐的方法,因为这可能会导致对象不同步。始终处理托管对象更好。

您还正在访问一个名为myRealm的变量,我认为该变量是对您的Realm的全局引用。请注意,对于托管对象,可以访问getRealm()函数以检索对象的领域,并避免使用全局变量/传递参数。

因此,最好是:


创建Visit时将其添加到领域
addTimeSlot中,使用getRealm()的结果验证是否管理了Visit。如果是这样,请将TimeSlot添加到Realm和RealmList。


我对您的TimeSlot主键的工作方式感兴趣。

无论如何,回到您的问题。


  当我从Realm检索myVisit时,是否可以保证myVisit.timeslots中的TimeSlot对象与添加它们时的顺序相同?


是。 RealmList已订购。您可以将元素添加到末尾,也可以通过添加RealmList来添加。如果未存储订单,这显然是多余的。请参见the docs


  文档提到非托管对象就像简单的POJO。据我了解,如果我创建RealObject子类实例并且从不费心将其复制到Realm,它将保持“不受管”状态。


正确。


  但是,如果我将其添加到作为“托管” RealmObject一部分的RealmList实例中会发生什么?


here中讨论。然后,您的列表就是一个托管领域列表,该语句适用:


  可以将非托管对象添加到已托管的RealmList中。在这种情况下,如果对象具有主键,则将使用Realm.copyToRealm(RealmModel,ImportFlag ...)或Realm.copyToRealmOrUpdate(RealmModel,ImportFlag ...)将对象透明地复制到Realm。


请注意,尽管您对对象的现有引用是对象的非托管版本,所以请当心。更改其字段不会更改托管版本。此时,最好放弃您的非托管版本,而仅处理托管对象。

我明白你为什么感到困惑。希望对您有所帮助。

关于java - 如何持久保存引用的RealmObjects,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59693019/

10-09 13:32