CoreData + iCloud + Cascade Delete: ¿cómo se maneja?

78

CoreData La entidad "A" tiene una relación de uno a varios con una colección de CoreData entradas "B", mediante una regla de eliminación en cascada.

En un iCloud entorno, mientras que el dispositivo 1 muestra una vista detallada de una de las entradas "B", el dispositivo 2 elimina la entrada "A".

Cuando NSPersistentStoreDidImportUbiquitousContentChangesNotificationse recibe la notificación en el dispositivo 1, su App Delegate llamamergeChangesFromContextDidSaveNotification y luego transmite una notificación interna que es capturada por el controlador de vista mostrando los detalles de la entrada "B" (el código usa performBlockdonde debería).

Sin embargo, aunque la entrada "A" se anula cuando el controlador de vista de detalles recibe la notificación interna, la entrada "B" todavía existe como una CoreData objeto . Parece que la regla Cascade aún no ha completado su operación. Por lo tanto, el controlador de vista en el dispositivo 1 no está al tanto de la eliminación, lo que puede generar resultados inesperados.

mergeChangesFromContextDidSaveNotification parece regresar prematuramente, cuando los datos base se han fusionado pero la regla en cascada aún no se ha completado.

Intenté actualizar la entrada "B" cuando llega la notificación mientras configuraba temporalmente la stalenessInterval contexto del objeto administrado en cero para que no se usara un objeto almacenado en caché, pero todavía obtengo una entrada válida "B" de la tienda.

Comprobando un null entrada "A" en este punto no es una opción, porque la situación es algo más compleja de lo que describí aquí y una entrada nula "A" puede ser válida en algunos casos.

Intenté introducir un retraso después de fusionar los cambios y antes de enviar la notificación interna a los controladores de vista. Descubrí que un retraso de 2 segundos no ayuda, pero un retraso de 10 segundos funciona.

Pero no quiero depender de este retraso. Este es un entorno de prueba sin muchos datos y no sé qué pasará en un entorno de producción. Depender de un retraso experimental no parece lo correcto.

¿Hay algo correcto? ¿O estoy haciendo algo mal para empezar?

Amiram Stark
fuente
Hay más de lo que parece, ya que las eliminaciones en cascada se propagan tan pronto como lo que viene primero: processPendingChanges, save o final de un ciclo de ejecución. En condiciones normales, el problema que describe no debería existir.
svena
¿Cuál es el ID de objeto administrado para el objeto en el controlador de vista detallada en la matriz NSDeletedObjectsKey que viene con NSPersistentStoreDidImportUbiquitousContentChangesNotification?
ImHuntingWabbits
¿Esto sucede siempre o es intermitente? ¡Tengo una estructura jerárquica compleja y todavía no he visto a ningún huérfano! ¿Está recuperando la entidad B nuevamente, o podría ser que debido a que la está mostrando de alguna manera está reteniendo una referencia al objeto? ¿Qué sucede si cierras la aplicación y la vuelves a abrir, la entidad B sigue ahí?
Duncan Groenewald
3
@Amiram Un año y medio. ¿Recibiste tu respuesta? :)
Pale Blue Dot

Respuestas:

1

Por experiencia, escuchar otras notificaciones NSManagedObjectContextDidSaveNotificationes un gran lío y puede llevar a confiar en propiedades que aún no se han actualizado. El controlador de vista de detalles debe escuchar las NSManagedObjectContextDidSaveNotificationnotificaciones, que se lanzan después de que se aplica la cascada. A continuación, puede verificar por varios medios si el objeto actual es válido o no (puede verificar si el contexto del objeto administrado del objeto actual lo es nilo puede realizar una búsqueda y ver si el objeto existe en la tienda).

Leo Natan
fuente