2009-05-11 10 views
10

estoy usando la observación de valor clave en una propiedad booleana un método NSObject:Clave Valor Observando en Cocoa, analizando el cambio de propiedad

-(void)observeValueForKeyPath:(NSString *)keyPath 
        ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context 

La parte más interesante del valor de esta ruta de la clave es un BOOL cuales está constantemente volteando entre SÍ/NO. Lo máximo que obtengo del diccionario de cambios es kind = 1. ¿Hay alguna manera sin probar el objeto que estoy observando para ver cuál es el valor de cambio real?

Gracias.

Respuesta

20

En primer lugar, se especifica NSKeyValueObservingOptionNew:

[theObject addObserver: self 
      forKeyPath: @"theKey" 
       options: NSKeyValueObservingOptionNew 
       context: NULL]; 

... entonces, en su método de observador:

-(void) observeValueForKeyPath: (NSString *)keyPath ofObject: (id) object 
         change: (NSDictionary *) change context: (void *) context 
{ 
    BOOL newValue = [[change objectForKey: NSKeyValueChangeNewKey] boolValue]; 
} 

Lo ideal sería comprobar si el valor era nil (bueno, es podría suceder) antes de llamar al -boolValue, pero se omitió para mayor claridad aquí.

+0

¿Cómo puede usted conseguir "cero"? Podría suceder para cualquier cosa del tipo NSObject, pero no veo cómo podría suceder eso con un BOOL. – Adam

+0

Quiero decir que verificaría si el resultado de '[change objectForKey: NSKeyValueChangeNewKey]' era 'nil', porque hay una diferencia entre 'no result' y 'a result of' NO''. –

+1

@JimDovey - cuando inspecciono el diccionario en la consola de depuración para una propiedad que no sea BOOL, me pregunto si una verificación literal de cadena no es necesaria también 'new =" "' – pulkitsinghal

19

Como dice Jim Dovey, excepto que el diccionario cambio no aporta nada, pero los valores nulos, por lo que

NSLog(@"%@", [change description]); 

dará lugar a algo como:

{ 
    kind = 1; 
    new = <null>; 
    old = <null>; 
} 

Como se ha mencionado, llamando BOOLVALUE en un valor nulo dará como resultado un error

[NSNull boolValue]: selector no reconocido enviado a la instancia 0xa0147020

Para evitar esto, hay que verificar para no nula, pero para [NSNull nula], así:

if([change objectForKey:NSKeyValueChangeNewKey] != [NSNull null]) 
    BOOL newValue = [[change objectForKey: NSKeyValueChangeNewKey] boolValue]; 

o

id newValue; 
if((newValue[change valueForKey: @"new"]) != [NSNull null]){ 
    BOOL newBOOL = [newValue boolValue]; 
} 
+0

Busqué y descubrí esta publicación. Tengo el mismo problema que devuelve new = null. http://stackoverflow.com/q/11835607/772481 ¿Esto es fijo? – angelokh

+0

Duda de que esto alguna vez se arregle. En su pregunta, se encuentra con un problema al observar una relación, lo que complica las cosas.Como mencioné allí desde los documentos "Si la propiedad observada es una relación muchos, la entrada NSKeyValueChangeKindKey también indica si los objetos en la relación se insertaron, eliminaron o reemplazaron al devolver NSKeyValueChangeInsertion, NSKeyValueChangeRemoval, o NSKeyValueChangeReplacement, respectivamente." –

Cuestiones relacionadas