views:

839

answers:

2

Hey all,

I'm using key value observing on a boolean property an NSObject method:

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

The most interesting part of the value for this key path is a BOOL which is constantly flipping between YES/NO. The most I get out of the change dictionary is kind = 1. Is there anyway without probing the object I'm observing to see what the actual change value is?

Thanks.

+6  A: 

Firstly, you specify NSKeyValueObservingOptionNew:

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

…then, in your observer method:

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

Ideally you'd check whether value was nil (well, it might happen) before calling -boolValue, but that was omitted for clarity here.

Jim Dovey
+4  A: 

As Jim Dovey says, except that the change dictionary does not bring nil, but null values, so that

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

will result in something like:

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

As mentioned, calling boolValue on a null value will result in an error

[NSNull boolValue]: unrecognized selector sent to instance 0xa0147020

To avoid this, one has to check not for nil but for [NSNull null], like so:

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

or

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