Наблюдение за ключевыми значениями в Cocoa, интроспекция свойства изменения

Я использую наблюдение за ключевыми значениями в булевом свойстве методом NSObject:

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

Самая интересная часть значения для этого ключевого пути - это BOOL, который постоянно переворачивается между YES/NO. Самое большее, что я получаю из словаря изменений: kind = 1. В любом случае, не проверяя объект, который я наблюдаю, чтобы увидеть, что такое фактическое значение изменения?

Спасибо.

Ответ 1

Во-первых, вы указываете NSKeyValueObservingOptionNew:

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

... тогда, в вашем методе наблюдателя:

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

В идеале вы должны проверить, было ли значение nil (ну, может случиться) до вызова -boolValue, но для ясности это было опущено.

Ответ 2

Как говорит Джим Дови, за исключением того, что словарь изменений не приносит нулевые, но нулевые значения, так что

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

приведет к чему-то вроде:

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

Как уже упоминалось, вызов boolValue при нулевом значении приведет к ошибке

[NSNull boolValue]: непризнанный селектор, отправленный в экземпляр 0xa0147020

Чтобы этого избежать, нужно проверить не на ноль, а на [NSNull null], например:

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

или

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