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 { }
,