4 cosas que debes de saber sobre NSManagedObjectContextObjectsDidChangeNotification y Core Data

Autor: | Última modificación: 15 de marzo de 2024 | Tiempo de Lectura: 2 minutos
Temas en este post:

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.

The infinity set, casi como el NSManagedObjectContextObjectsDidChangeNotification

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.

// No pases nil al parámetro de object, que te inundan de 
// notificaciones que no te interesan.
-(void) susbcribeToNotificationsFrom:(NSManagedObjectContext*) context{

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self
           selector:@selector(notificationThatContextDidChange:)
               name:NSManagedObjectContextObjectsDidChangeNotification
             object:context];
}

Y así es como se da un buen uso a la notificación NSManagedObjectContextObjectsDidChangeNotification. Si quieres aprender más sobre desarrollo, echa un vistazo a nuestros bootcamps de programación y tecnología.