领域 - 删除后数据库不是最新的

时间:2016-10-19 12:05:26

标签: ios swift realm

我的Realm数据库中有一些对象。我需要从中删除一个对象。 当我从Realm()实例中删除我的对象时,对象被删除

但是在执行删除请求之后,我需要从数据库中检索所有对象,但是出乎意料的是,对象仍然在这里

我认为我有一个线程问题,或类似的东西。 我不知道在哪里调查。

我的简化代码:

我的删除方法:

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

从viewController调用此方法,执行完成块。 此完成块包含从我的Realm数据库中检索所有对象的请求:

执行方法和完成块的viewController:

 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
        // ...
    }
}

我认为我的2 realm个实例不同,或者线程之间存在问题,因为我有DispatchQueue.main.async

有什么想法吗?

编辑:

我注意到当我检查断点时,有时它会起作用。

那么也许还没有提交删除请求,并且我在删除请求结束之前检索了对象?

2 个答案:

答案 0 :(得分:1)

确保将async块放在自动释放池中:

 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
        // ...
    }
}

应该是

 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
            // ...
        }
    }
}

确保为主要在GCD中创建Realm实例的任何后台线程执行此autoreleasepool { ... }换行。

如果仍然不起作用,您可以这样做:

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

答案 1 :(得分:1)

Realm隔离每个线程上的事务,以避免来自一个线程的更改立即影响另一个线程。这种机制也避免了ORM固有的“缺陷”。

在您的代码中,您可以选择在您控制的点处刷新(推进)领域到最新状态,并且可以在刷新不同之前和之后处理数据。

默认情况下,在runloop的每次迭代中,带有runloop(例如主线程)的线程上的域都会自动前进。

在您的代码示例中,您在从另一个线程提交后立即调用DispatchQueue.main.async,这意味着如果您在主线程上已经有一个Realm,则异步块将处于相同的状态,并且不会包括最后一次提交。

但您可以在异步块的开头显式调用Realm.refresh(),这将确保此块看到最后一次提交:

myDeleteFunc(completion: {
    DispatchQueue.main.async {
        let realm = try! Realm()                  
        realm.refresh()
        let objects = Array(realm.objects(MyObject.self).sorted(byProperty: "aProperty"))
        // ...
    }
}

有关详细信息,请参阅Seeing Changes From Other Threads上的Realm文档。