2016-10-19 4 views
0

У меня есть некоторые объекты в моей базе данных 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.

Любые идеи?

EDIT:

Я заметил, что когда я проверяю с контрольными точками, иногда это работает.

Возможно, что запрос на удаление еще не завершен и что я возвращаю объекты до конца запроса на удаление?

ответ

1

Убедитесь, что вы положили async блок в autorelease бассейне:

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

Убедитесь, что вы делаете это autoreleasepool { ... } обертку для любого фонового потока, где вы создаете экземпляр Realm, прежде всего в ГДР.


Если этот еще не работает, вы можете сделать:

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

Он работает с autoreleasepool и realm.refresh(), спасибо, но зачем мне это делать? – AnthonyR

+0

Ну, технически часть 'refresh()' скорее является обходным решением, если оно все еще не работает, хотя это означает, что у вас все еще есть открытые экземпляры Realm, которые вы должны обертывать блоком 'autoreleasepool', чтобы обеспечить их закрытие. – EpicPandaForce

+0

Хорошо, спасибо, я проверю этих призраков! – AnthonyR

1

Realm изолирует операции на каждом потоке, чтобы избежать изменения от одного потока сразу же влияют на другой. Этот механизм также позволяет избежать «ошибок», присущих ORM.

В вашем коде вы можете обновить (продвинуть) область до последнего состояния в точках, которые вы контролируете и можете обрабатывать данные до и после обновления.

Realms на потоке с 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")) 
     // ... 
    } 
} 

Смотрите документы Realm на Seeing Changes From Other Threads для получения дополнительной информации.

+0

Спасибо, это более понятно. Последний вопрос: Фактически в моем методе удаления я выполняю несколько запросов на удаление в цикле for на экземпляре Realm. Итак, основываясь на том, что вы сказали, если два потока могут быть выполнены одновременно, я делаю вывод, что экземпляры 2 Realm в моем коде могут отличаться, даже если я обновляю, нет? Потому что да, Царство будет обновлено с последним фиксацией. Но после обновления, может быть, что некоторые запросы на удаление все еще не готовы? – AnthonyR

Смежные вопросы