修改数组中的Realm对象而不提交?

时间:2018-03-22 18:35:09

标签: ios swift realm

我正在更新一个Realm对象数组:

for offer in offers {
     if(offer.isReward == isReward){
        offer.isSeen = true
     }
}

但它引发了一个错误:

Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.

我知道我可以这样做:

for offer in offers {
  if(offer.isReward == isReward){
      try! offer.realm?.write {
          offer.isSeen = true
      }
  }
}

无论如何,我可以推迟写入Realm,直到我对数组中的所有元素进行更改并提交整个数组?对每个需要更改的对象进行写入事务似乎效率低下。

我原来的计划是修改项目和批量更新

 try realm.write {
     realm.add(offers, update: true)
 }

2 个答案:

答案 0 :(得分:2)

对托管Realm对象的所有更改都需要在写入事务中进行。您无法修改托管对象,然后将更改写入Realm,因为托管对象“永不离开”Realm,因此您对其所做的任何更改都将立即保存。

如果没有看到有关代码的更多上下文,我无法为您提供具体的实现,但一般情况下(至少)有两种方法可以解决此问题。

首先,您始终可以创建托管对象的副本,然后逐个修改这些副本的值,并在完成后在单个写入事务中从其副本更新所有托管对象。但是,这需要在内存中存储两倍的对象,因此它不是最佳解决方案。

第二种解决方案更优化,但仅适用于某些情况。您可以简单地将当前具有的整个代码包装在写入事务中,并遍历写入事务中的托管对象。这样,您只使用单个事务,但更新所有托管对象而不复制它们。但是,您不应该在写入事务中执行计算上昂贵的进程,因此如果您需要在更新对象时执行持久的任务,这也不是最佳解决方案。

没有一种好的写事务方式。在单个事务中更新的对象数量与使用多个事务更新少量对象之间存在权衡。

答案 1 :(得分:1)

如果您保留realm本身的实例,请致电beginWrite(),执行您的更改循环,然后commitWrite()

let realm = try! Realm()
//let offers = realm.... look up your objects
realm.beginWrite()
for offer in offers {
     if(offer.isReward == isReward){
        offer.isSeen = true
     }
}
try! realm.commitWrite()