Наблюдение за ключевыми значениями в 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];
}