objective c - Observando los cambios de NSMutableDictionary
objective-c (2)
Esa es una idea interesante. No puedo encontrar nada en NSDictionary o NSDictionaryController que parezca prometedor. Mi primer instinto sería utilizar la composición en torno a un NSMutableDictionary e interceptar llamadas a setObject: forKey: (y tal vez -removeObjectForKey :) para notificar los cambios a los suscriptores.
Hay un post de Cocoa With Love en la subclasificación de NSMutableDictionary que probablemente sea útil si decides ir por esa ruta. También he creado mis propias subclases de NSMutableDictionary , y puede utilizar el código de código abierto.
Podría diseñar un protocolo de observador que podría especificar claves particulares que deberían ser monitoreadas. No debería ser demasiado código, pero más de lo que tengo tiempo para tirar en este momento.
¿Es posible observar (suscribirse a) cambios en los valores almacenados bajo diferentes claves en un NSMutableDictionary? En mi caso, las claves ya existirían cuando se inicie la suscripción, pero los valores cambian y me gustaría ser notificado en este caso. Me gustaría la clave del valor cambiado en la notificación.
Supongo que si mis claves de diccionario fueran todas las instancias de NSString, podría suscribirme individualmente a cada ruta de acceso de clave. Pero ¿y si mis llaves no son cuerdas? ¿Estoy fuera de suerte en ese caso?
He implementado esto con éxito ahora, usando la composición en torno a NSMutableDictionary. Me sorprende lo poco que tomó el código. La clase que implementé es Board, que se utiliza para representar el modelo en un juego de mesa. Cualquier persona puede suscribirse a los cambios para los estados de la junta llamando al método addObserver: implementado de esta manera:
- (void)addObserver:(id)observer {
for (id key in grid)
[self addObserver:observer
forKeyPath:[key description]
options:0
context:key];
}
Como solo puedes suscribirte a las claves con el modelo KVO, hice trampa y me suscribí a la descripción de la clave, pero pasé la clave como contexto. En los objetos que observan instancias de mi Tablero, implemento el -observeValueForKeyPath:ofObject:change:context:
para ignorar la cadena keyPath y solo usar el contexto pasado.
Mi clase de tablero simple no es compatible con KVO para las propiedades artificiales que creo usando este método, así que pasé 0
en la propiedad de options
para que la maquinaria KVO no intente obtener los valores antiguos / nuevos de esas claves. Eso causaría que mi código explotara.
Cualquier cosa que cambie la placa (en mi clase simple solo hay un método que hace esto) eleva las notificaciones necesarias para hacer que la maquinaria KVO se ponga en acción:
- (void)setPiece:(id)piece atLocation:(Location*)loc {
[self willChangeValueForKey:[loc description]];
[grid setObject:piece forKey:loc];
[self didChangeValueForKey:[loc description]];
}
Voila! Suscripción a un NSMutableDictionary con claves no de cadena!