Observe correctamente el object usando KVO

Tengo una vista que está observando las properties de un solo object usando KVO. He observado todas las properties del object en la vista.

[person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:NULL]; [person addObserver:self forKeyPath:@"photo" options:NSKeyValueObservingOptionNew context:NULL]; [person addObserver:self forKeyPath:@"address" options:NSKeyValueObservingOptionNew context:NULL]; 

Ahora, cuando hay un cambio en una sola propiedad, parece estar bien, pero cuando cambia todo el object, la notificación se activa 3/4 veces en solo una fracción de segundos. Necesito cargar los datos de la networking en function de los cambios. Mientras que un solo cambio de propiedad crea una sola request de networking, pero si cambian varias properties al mismo time. Crea una queue de request para el mismo object. Esto lleva a algún problema. ¿Cómo puedo observar múltiples properties al mismo time y cargar solo una vez, incluso si todas las properties cambian? Por favor, ayúdame. Este es un problema serio en el que me he metido.

Puede usar una fuente de despacho en Grand Central Dispatch para unir las observaciones de cambio de propiedad para que no ocurran con más frecuencia de lo que puede manejarlas.

 @implementation Controller { dispatch_source_t source; } - (id)init { self = [super init]; if (self) { //We are using data add source type, but not actually using the added data. source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue()); dispatch_source_set_event_handler(source, ^{ //Insert your network call to load data from the network. //The event handler will only be called when another event handler is not being processed. So you won't attempt to do another network call until the last call was completed. }); //Dispatch sources always start out suspended so you can add the event handler. You must resume them after creating them if you want events to be delivenetworking) dispatch_resume(source); } return self; } - (void)dealloc { dispatch_release(source); } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { //Tell dispatch source some data changed. It will only call the event handler if an event is not currently being handled. //You could add a custom timer based coalesce here for when no events are currently being processed if you want to delay all initial events to potentially wait for more changes dispatch_source_merge_data(source, 1); } @end 

Entonces, la primera notificación de cambio de propiedad desencadena el controller de events de origen de envío. Los cambios de propiedad subsiguientes que ocurren mientras se está ejecutando un evento existente se ponen en queue para ejecutarse tan pronto como se completa el último. Esto significa que si 5 properties cambian en rápida sucesión, obtendrá 2 llamadas de networking (en lugar de 5 llamadas de networking). Puede agregar un coalesce basado en el timer personalizado cuando no se están procesando events si prefiere sacrificar la capacidad de respuesta instantánea a las notifications para eliminar la segunda llamada de networking.