2015-06-10 23 views
7

我为我的项目使用RealmSwift。但是,我不知道如何处理以下内容:RealmSwift RLMException

RMLException:试图修改写入事务以外的对象 - 上RLMRealm例如第一

抛出调用beginWriteTransaction

任何人有任何线索?

import RealmSwift 

func createOrUpdateMachineInRealm(machine: Machine){ 

    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT 

    dispatch_async(dispatch_get_global_queue(priority, 0)) { 
     // do some task 
     let realm = Realm() 

     realm.beginWrite() 

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

     realm.commitWrite() 

     dispatch_async(dispatch_get_main_queue()) { 
      // update some UI 
      actionDelegate?.operationCompleted(true) 
     } 

    } 
} 

解决方案:我通过在机器的参数,以及和他们realm.write()

func createOrUpdateMachineInRealm(machine: Machine, name: String){ 

    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT 

    dispatch_async(dispatch_get_global_queue(priority, 0)) { 
     // do some task 
     let realm = Realm() 

     realm.write{ 
      machine.name = name 
      realm.add(machine, update: true) 
     } 
    } 

} 

回答

9

我刚刚遇到了和你一样的问题和异常。尽管Nate Mann的答案不是解决问题的方法,但它使我朝着正确的方向前进。

您不能修改以前从数据库中取出的Realm对象,因为Realm会尝试更新它并在不同的队列上发生错误(无论出于何种原因)。

因此,您必须在realm.write{ }语句中进行所有修改,或使用相同的主键创建新对象,以便正确更新。这也意味着你不能有一个函数来创建更新,但需要两个单独的函数。

您的更新功能将不得不是这个样子:

func updateMachineInRealm(machine: Machine){ 
    var updatedMachine = Machine() 
    updatedMachine.name = machine.name 
    updatedMachine.value = machine.value + 42 
    updatedMachine.primaryKey = machine.primaryKey 
    // "transfer" or modify all the values of the old machine object 

    let realm = try! Realm() 
    do { 
     try realm.write() { 
     realm.add(updatedMachine, update: true) 
    } 
} 

请记住,你需要为这个代码工作的唯一主键,因为那是什么境界将与匹配数据库中新对象。

此外,当工作在一个更大的项目上有多个线程访问Realm对象等时,这当然有缺点。但它可以用于小型项目(就像我正在处理的那样,而且您似乎正在开发)。

5

摆脱realm.beginWrite()realm.commitWrite()内分配给设备。当您使用realm.write { }时,不需要它们。

+0

感谢您的回复@NateMann。我可以在第一次没有错误时添加它。然而,由于未捕获的异常'RLMException',我得到了这个***终止应用程序,理由是:'尝试修改写事务之外的对象 - 首先调用RLMRealm实例上的beginWriteTransaction。'当我再次调用该方法时更新)。 – perwyl

+1

您正在添加一台机器或正在更新一台机器。如果你正在更新一个,比如说machine.name =“Drill”,这个必须在Realm()。write {}中完成,就像这个Realm()写入{machine.name =“Drill”} –

+0

是否有可能我在UI级别更新Machine对象并传递给Realm()(Storage.swift)进行写入事务?我试图避免在ViewControllers中使用Realm。 realmSwift非常新 – perwyl