2009-05-11 10 views
10

sto usando valore chiave osservando su una proprietà booleana un metodo NSObject:Chiave Valore Osservando in Cocoa, l'introspezione del cambiamento di proprietà

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

La parte più interessante del valore per questo percorso di chiave è un BOOL che è costantemente girando tra SI/NO. Il massimo che ottengo dal dizionario delle modifiche è kind = 1. Esiste comunque senza sondare l'oggetto che sto osservando per vedere quale sia il valore effettivo del cambiamento?

Grazie.

risposta

20

In primo luogo, si specifica NSKeyValueObservingOptionNew:

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

... poi, nel vostro metodo di osservatore:

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

Idealmente si avrebbe controllato se il valore è stato nil (beh, potrebbe accadere) prima di chiamare -boolValue, ma questo è stato omesso per chiarezza qui.

+0

Come hai potuto ottenere "nil"? Potrebbe accadere per qualcosa di tipo NSObject, ma non vedo come potrebbe accadere per un BOOL? – Adam

+0

Voglio dire che si controllerebbe se il risultato di '[change objectForKey: NSKeyValueChangeNewKey]' era 'nil', perché c'è una differenza tra 'nessun risultato' e 'un risultato di' NO''. –

+1

@JimDovey - quando controllo il dizionario sulla console di debug per una proprietà non BOOL, mi chiedo se non sia richiesto un controllo letterale stringa 'new =" "' – pulkitsinghal

19

Come dice Jim Dovey, salvo che il dizionario cambiamento non porta nulla, ma i valori nulli, in modo che

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

si tradurrà in qualcosa di simile:

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

Come detto, chiamando BOOLVALUE su un valore nullo si verificherà un errore

[NSNull boolValue]: selettore non riconosciuto inviato all'istanza 0xa0147020

Per evitare questo, si deve controllare, non per nulla, ma per [NSNull null], in questo modo:

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

Ho cercato e ho scoperto questo post. Ho lo stesso problema che new = null restituito. http://stackoverflow.com/q/11835607/772481 È stato risolto? – angelokh

+0

Dubita che questo possa mai essere risolto. Nella tua domanda ti imbatti in un problema osservando una relazione, che complica le cose.Come ho citato dai documenti "Se la proprietà osservata è una relazione to-many, la voce NSKeyValueChangeKindKey indica anche se gli oggetti nella relazione sono stati inseriti, rimossi o sostituiti restituendo rispettivamente NSKeyValueChangeInsertion, NSKeyValueChangeRemoval o NSKeyValueChangeReplacement." –

Problemi correlati