2017-01-27 4 views
1

При сохранении объекта асинхронно в фоновом режиме я получаю RLMException: «Невозможно добавить объекты из другого королевства». Однако одно и то же сохранение отлично работает, если удалить асинхронный код.RLMException при сохранении объекта в фоновом потоке

Этот объект имеет отношение к существующему объекту. Например:

class Person: Object { 
    name: String 
    school: School 
} 

class School: Object { 
    name: String 
} 

let person = new Person() 
person.name = "John" 
person.school = school // Existing object selected from a dropdown. 

DispatchQueue.global().async { 
    do { 
     let realm = try Realm! 

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

     DispatchQueue.main.async { 
      // Success! 
     } 
    } catch let error as NSError { 
     DispatchQueue.main.async { 
      // Error! 
     } 
    } 
} 

Этот код приводит к сбою. Однако, если я удалю DispatchQueye.global(). Async, все работает нормально. Есть ли какая-то проблема с потоками, с которой я сталкиваюсь?

Примечание: объект school еще не существует и выбран из коллекции Results<School>.

ответ

4

Объекты Realm Object нельзя перемещать между потоками, как только они были сохранены в Realm. Поскольку school будет объектом, который был создан в основном потоке, вы создаете конфликт, присоединяя его к неустановленному объекту и перемещая лот в фоновый поток.

Чтобы исправить это, вам необходимо сделать фоновый вариант объекта school, используя Realm's thread reference feature.

Кроме того, если у вас нет конкретной причины для создания Person в основной теме, я бы также рекомендовал переместить его создание в фоновый поток.

let schoolRef = ThreadSafeReference(to: school) 

DispatchQueue.global().async { 
    do { 
     let realm = try Realm! 

     let person = new Person() 
     person.name = "John" 
     person.school = realm.resolve(schoolRef)! 

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

     DispatchQueue.main.async { 
      // Success! 
     } 
    } catch let error as NSError { 
     DispatchQueue.main.async { 
      // Error! 
     } 
    } 
} 
+0

Спасибо, что указал мне в правильном направлении. Одна из ошибок, которые я делал, - это создать человека на главной теме, как вы указали. Ура! – melsam

+0

Не беспокойтесь! Рад, что смог помочь! :) – TiM

+0

Я чувствую, что Realm может сделать с лучшей документацией. –