AnthonyR AnthonyR - 1 month ago 8
iOS Question

Realm - database isn't up to date after a delete

I've got some objects in my Realm database. I need to delete an object from it.
When I delete my object from my

Realm()
instance, the objects are well deleted.

But after performing the delete request, I need to retrieve all objects from the database, but here surprise, the object is still here.

I think I have a thread problem, or something like that.
I don't know where to investigate.

My simplified code :

My delete method :

func myDeleteFunc(completion : ()->Void){
let realm = try! Realm()
// ...
try! realm.write {
realm.delete(myObject)
}
completion()
}
// Here the object have been deleted from the realm instance, no problem


This method is called from a viewController where I execute the completion block.
This completion block contains the request that retrieve all objects from my Realm database :

The viewController that executes the method and the completion block :

myDeleteFunc(completion: {
DispatchQueue.main.async {
let realm = try! Realm()
let objects = Array(realm.objects(MyObject.self).sorted(byProperty: "aProperty"))
// Here objects still contains the object that I have already deleted
// ...
}
}


I think my 2
realm
instances differs, or have problems between threads because I have a
DispatchQueue.main.async
.

Any ideas ?

EDIT :

I noticed that when I check with breakpoints, sometimes it works.

So maybe that the delete request have not been committed yet, and that I retrieve the objects before the end of the delete request ?

Answer

Make sure you put the async block in an autorelease pool:

 myDeleteFunc(completion: {
    DispatchQueue.main.async {
        let realm = try! Realm()                  
        let objects = Array(realm.objects(MyObject.self).sorted(byProperty: "aProperty"))
        // Here objects still contains the object that I have already deleted
        // ...
    }
}

Should be

 myDeleteFunc(completion: {
    DispatchQueue.main.async {
        autoreleasepool {
            let realm = try! Realm()                  
            let objects = Array(realm.objects(MyObject.self).sorted(byProperty: "aProperty"))
            // Here objects still contains the object that I have already deleted
            // ...
        }
    }
}

Make sure you do this autoreleasepool { ... } wrap for any background thread where you create a Realm instance, primarily in the GCD.


If that still doesn't work, you can do:

 myDeleteFunc(completion: {
    DispatchQueue.main.async {
        autoreleasepool {
            let realm = try! Realm()                  
            realm.refresh()
Comments