2012-07-04 8 views
18

Actualmente estoy teniendo un problema donde crear un nuevo objeto en un subproceso secundario (cuyo elemento principal es el contexto principal de la interfaz de usuario) y guardar hace que mi NSFetchedResultsController muestre dos objetos nuevos: uno con un objectID temporal y otro con un permanente objectID. Esto parece ser un error de algún tipo, a menos que me falta algo.¿Cuándo llamar para obtener ID Permanente para Objetos :?

Así que pensé que obtendría manualmente identificaciones permanentes para cualquier objeto nuevo que crease. Esto corrige el problema de la fila duplicada, pero introduce nuevos errores aleatorios (como "no se pudo cumplir la falla para el objeto", refiriéndose al nuevo objeto que creé). Si alguien tiene alguna idea de por qué está sucediendo algo de lo mencionado anteriormente, por favor compártelo.

Supongo que obtainPermanentIDs es un paso en la dirección correcta. ¿Pero cuándo llamo a este método? Antes de guardar en el contexto del niño? Después de guardar al niño y antes de los padres? Después del padre? Actualmente mi configuración es la siguiente:

masterMOC - private queue tied to the persistent store, so physical saves happen here 
----mainMOC - main queue tied to the UI, child of masterMOC 
-------backgroundMOC - private queue, child of mainMOC 

lo tanto, si se crea un nuevo objeto en backgroundMOC, y tengo la intención de avisar inmediatamente guardar en el disco (lo que significa que voy a tener que llamar a ahorrar: en los tres contextos), donde ¿Debería llamar al obtainPermanentIDs?

(o si alguien tiene una solución diferente que no sea llamando obtener los identificadores permanentes Qué problema era este método introducido para resolver todos modos ¿Por qué querría llamar a este método???)

Actualización: creo Me di cuenta de lo que está pasando (aunque es solo una teoría), aunque no cómo resolverlo. Core Data aparentemente genera ID permanentes para los objetos cuando se guardan físicamente en el disco. Entonces, en mi caso, esto no sucederá hasta que llame a save en el masterMOC. Actualmente lo que hago cuando se crea un nuevo objeto en el backgroundMOC es:

  1. ahorrar en backgroundMOC (de modo que los cambios son empujados hacia arriba un nivel al mainMOC y mi vista de tabla se pueden insertar las nuevas filas)
  2. Guardar en mainMOC (para que pueda prepararse para guardarlo en el disco)
  3. ahorrar en masterMOC (que finalmente se guarda en el disco)

lo que sucede aquí es que llamar a save en el backgroundMOC desencadena una actualización de la interfaz de usuario, y hace que la Se obtuvo el controlador de resultados para insertar un nuevo objeto que todavía tiene en una identificación temporal. Pero al llamar a save en masterMOC, todos los objetos reciben identificadores permanentes asignados, lo que causa otra actualización de UI, ¡insertando otra fila para este "nuevo" objeto! Al comentar el último save de masterMOC, ya no veo entradas duplicadas. ¿Estoy haciendo algo mal aquí, o es esto algún tipo de error?

Otra actualización: Creo que prácticamente confirmé el error. Llamo a guardar en el backgroundMOC y luego configuro un temporizador para llamar a guardar en el mainMOC y masterMOC 5 segundos después. Inmediatamente después de guardar en backgroundMOC, se inserta una nueva fila en mi tabla. 5 segundos después (al guardar principal y principal), se inserta otra fila nueva. (la fila insertada primero tiene una identificación temporal, y la más reciente tiene una identificación permanente).

Respuesta

11

Tuve exactamente el mismo problema, por supuesto después de un día particularmente difícil y desalentador de depurar todo para descubrir que el problema eran los ID temporales.:)

Tengo exactamente la misma estructura que usted, y también tengo subclases de NSManagedObjectContext para codificar el comportamiento que espero de los salvados en el contexto principal y fondo, es decir, un guardado en el contexto de fondo debe guardar el contexto principal (y el contexto principal debe sincronizar cualquier objeto que haya cambiado con el servicio externo, lo cual es irrelevante, pero vale la pena mencionarlo como una explicación de por qué tengo dos subclases), y guardar en el contexto principal debe guardar el contexto maestro.

En mi subclase RFSImportContext (equivalente a su backgroundMOC), implemento - save: llamar [super save:], a continuación, llamar [self.parentContext performBlock:] (self.parentContext aquí es equivalente a su mainM) C, donde el bloque llama obtainPermanentIDsForObjects: con el contenido de la principal de contexto - updatedObjects y - insertedObjects matrices, luego guardo el contexto principal.

Ya no tengo la fuga de objetos temporales en mi NSFetchedResultsController como usted describe. Una forma de mejorar un poco la situación sería utilizar la subclase RFSMainContext (una vez más, equivalente a su mainMOC) para implementar - save: para obtener ID de objeto permanentes, guardarse a sí mismo y luego guardar el contexto maestro. Esto codifica el comportamiento de que siempre queremos que el contexto principal tenga ID permanentes para los objetos cuando se guarda.

+2

su comentario de alguna manera me ayudó pero de otra manera. Estaba usando un NSFetchedresultscontroller y obtenía temporalIds además de permanente. De modo que cada vez que el controlador llama a \ nchangecontent, hago un getPermanentIDsForObjects: a todos los objetos recuperados y funciona perfectamente ahora. –

+0

@ JoãoNunes todavía no funciona para mí, mis identificaciones ya son permanentes y este error aún sigue incitándome –

+0

¿Qué tipo de error tienes? –

Cuestiones relacionadas