coreData

4 cosas que debes de saber sobre NSManagedObjectContextObjectsDidChangeNotification y Core Data

NSManagedObjectContextObjectsDidChangeNotification es una notificación que envía el NSManagedObjectContext de Core Data, cuando se produce algún cambio sobre alguno de los objetos que dicho contexto contiene. ¿Qué tipo de cambios? A saber:

  1. Cuando un objeto nuevo se inserta en el contexto. En Cristiano, esto significa “cuando creas un nuevo objeto en dicho contexto”.
  2. Cuando cambias la propiedad de alguno de los objetos que están dentro del contexto.
  3. Cuando destruyes alguno de los objetos que están dentro del contexto.

¡OJO! El primer caso es SOLO cuando se crea un NUEVO objeto. Si recuperas uno de la base de datos mediante un fetch, eso no cuenta y ¡no se enviará la notificación NSManagedObjectContextObjectsDidChangeNotification!

Confusiones con NSManagedObjectContextObjectsDidChangeNotification

He visto que con frecuencia esta notificación se usa mal, con consecuencias catastróficas en algunos casos. Sin embargo, para llevarse bien con NSManagedObjectContextObjectsDidChangeNotification, sólo hay que tener en cuenta un par de cosas. Bueno, mejor dicho un par de pares de cosas. 😉

Namber güán: la notificación se envía de forma aplazada

El NSManagedContext envía esa notificación a cada cierto tiempo y no inmediatamente después del cambio. Por lo tanto, no esperes ser notificado de inmediato. Serenidad y paciencia, mucha paciencia.

Namber chú: los cambios se consolidan antes de notificar

Antes de enviar las notificaciones, los cambios se consolidan. Esto se hace para evitar enviar más notificaciones de las estrictamente necesarias.

Por ejemplo, supongamos que creas un objeto y le cambias una propiedad. Esperarías dos notificaciones (una de creación y otra de cambio), ¿no es así? Pues NO. Recibirás solo la de inserción, pero ya con el nuevo valor de la propiedad.

Namber zrí: ¡No guardes el contexto desde el método en el que recibes la notificación!

Cuando se termina el RunLoop, el contexto recibe el mensaje processPendingChanges. Ahora bien, el contexto envía la notificación durante ese método, pero en un punto donde todavía NO es seguro llamar a save. Si lo haces, provocarás una fermosa recursión infinita.

fractal1

El hermoso mundo de la recursividad

Si es vital guardar después de recibir la notificación, hazlo de forma aplazada usando ya sea dispatch_after o performSelector:withObject:afterDelay:. De esta forma te aseguras que el guardado se ejecute una vez terminado processPendingChanges.

 

Namber for: hay más contextos de los que crees

 

Aunque sólo hayas creado un contexto, Core Data se ha encargado de crear otros más, por razones que ahora no vienen a cuento (aunque sean interesantes).

Moraleja: cuando te das de alta para esa notificación, especifica a cual contexto te refieres, porque si no, recibirás notificaciones de todos, y te volverás loco.

 

 

 

 

 

Acerca de Fernando Rodriguez

Fundador & Editor Jefe de justcodeit, Fernando Rodríguez (@frr149 & Linkedin) es desarrollador & un experto en la enseñanza de máxima calidad en programación y desarrollo para dispositivos iOS, Cocoa Touch, Objective C, Swift, Python, entre otros, aunque su mejor carta de presentación, es la opinión de sus alumnos: http://keepcoding.io/es/testimonio/ CLO en KeepCoding & Arunovo. Instructor de iOS Avanzado del Big Nerd Ranch. Profesor Asociado de la U-tad, autor invitado de revistas como iPhoneWorld, Applesfera.com & ponente habitual en conferencias dentro y fuera de España (iOSDevUK, CodeMotion, BCNDevCon, etc). En sus vidas anteriores fue un nerd de Python y Django, mago de Smalltalk, y para su pesar, galeote de C++ y un gran cocinero.

Share this:

Leave a comment