es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Eliminar fila de Realm a través de SwiftUI produce una excepción ‘El objeto ha sido eliminado o invalidado’.

Estoy intentando eliminar una fila de una lista SwiftUI que carga datos de una base de datos Realm, está implementada como aquí:

struct MyView: View {
    private let realm = try! Realm()

    var body: some View {
        List {
            ForEach(realm.objects(MyModelDB.self)) { model in
                MyRow(model: model)
            }
        }.onDelete { indexSet in
            try? realm.write {
                indexSet.forEach { index in
                    realm.delete(words[index])
                }
            }
        }
    }
}

Pero cuando intento eliminar, recibo una excepción:

  • Terminating app due to uncaught exception ‘RLMException’, reason: ‘Object has been deleted or invalidated.’

¿Qué está mal?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema es que estás intentando eliminar un objeto de la base de datos Realm utilizando el índice del elemento en la lista SwiftUI. Sin embargo, el índice del elemento en la lista SwiftUI puede no ser el mismo que el índice del elemento en la base de datos Realm. Por lo tanto, al eliminar un elemento utilizando el índice de la lista SwiftUI, es posible que termines eliminando el objeto equivocado o un objeto que ya ha sido eliminado.

    Para solucionar este problema, debes pasar el objeto del modelo que se va a eliminar al cierre onDelete en lugar de utilizar el índice para eliminar el objeto de la base de datos Realm. Así es cómo puedes modificar tu código:

    struct MyView: View {
        private let realm = try! Realm()
        private var models: Results<mymodeldb> {
            realm.objects(MyModelDB.self)
        }
    
        var body: some View {
            List {
                ForEach(models) { model in
                    MyRow(model: model)
                }
                .onDelete { indexSet in
                    try? realm.write {
                        indexSet.forEach { index in
                            let model = models[index]
                            realm.delete(model)
                        }
                    }
                }
            }
        }
    }
    

    En el código modificado, estamos obteniendo los modelos de la base de datos Realm utilizando una propiedad calculada llamada models. Esta propiedad devuelve una colección Results que se actualiza automáticamente cuando la base de datos cambia. Luego, estamos utilizando la colección models en lugar del método realm.objects(MyModelDB.self) en el bucle ForEach.

    En el cierre onDelete, estamos obteniendo el objeto del modelo que se va a eliminar de la colección models utilizando el índice del indexSet. Luego, estamos eliminando el objeto del modelo de la base de datos Realm utilizando el método realm.delete.

Comments are closed.