Reputation: 4977
When saving an object asynchronously in the background, I get RLMException: 'Can not add objects from a different Realm'. However, the same save works fine if remove the async code.
This object has a relationship to an existing object. For example:
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!
}
}
}
This code results in a crash. However if I remove the DispatchQueye.global().async, everything works fine. Is there some threading issue I'm running into?
Note: the school
object is pre-existing, and selected from a Results<School>
collection.
Upvotes: 1
Views: 1180
Reputation: 15991
Realm Object
instances can't be moved between threads once they've been saved to Realm. Since school
would be an object that was instantiated on the main thread, you're creating a conflict by attaching it to an un-persisted object and moving the lot to a background thread.
To fix this, you'll need to make a background version of the school
object using Realm's thread reference feature.
Also, unless you have a specific reason for creating Person
on the main thread, I'd also recommend moving its creation to the background thread too.
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!
}
}
}
Upvotes: 6