RealmSwift RLMException

Я использую RealmSwift для моего проекта. Тем не менее, я не уверен, как справиться со следующим:

RMLException: Попытка изменить объект вне транзакции записи - вызов beginWriteTransaction на RLMRealm первый экземпляр

выброшены.

У кого-нибудь есть подсказка?

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)
        }
     }

 }

2 ответа

Решение

У меня была та же проблема и исключение, что и у вас. Хотя ответ Нейта Манна не является решением проблемы, он ведет меня в правильном направлении.

Вы не можете изменить объект 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 будет сопоставлять ваш новый объект в базе данных.

Кроме того, у этого, конечно, есть недостатки при работе над большим проектом с более чем одним потоком, обращающимся к объектам Realm и т. Д. Но это будет работать для небольших проектов (как я работал, и вы, кажется, работаете).

Избавляться от realm.beginWrite() а также realm.commitWrite(), Они не нужны при использовании realm.write { },

Другие вопросы по тегам