В моем классе у меня есть два объекта данных: dataDict (свойство) и prevDict (переменная экземпляра), которые оба являются NSMutableDictionary
объектами.В этих многоуровневых словарях все «узлы» сами являются NSMutableDictionary
объектами, а все «листья» являются значениями NSString.
В большинстве случаев эти словари сравниваются, чтобы быть одинаковыми.Но когда новые входящие данные отличаются, я хочу зафиксировать эти изменения с помощью KVO, а затем сохранить новый входящий словарь.Рекурсивные вызовы - это то, что запускает все изменения KVO.
Ниже приведен код для рекурсивного определения, отличаются ли новые входящие данные (в свойстве «dataDict») от того, что в «prevDictionary».Начальный вызов:
[self postChangesFromPrevDict:prevDict usingKeyPath:@"dataDict"];
prevDict = [[NSMutableDictionary alloc] initWithDictionary:self.dataDict copyItems:YES];
Если есть изменение на данном листе, он должен обновить это в словаре и выдать уведомление KVO.
Пример строкового значения 'newPath' можетбыть "dataDict.group.name.points" - в котором значение ключа - это "points".
В отмеченной точке останова отладчика я могу видеть значения 'curStr' и 'newStr' как, скажем, «120» и «121», причем эти два значения правильно получены из prevDict
и dataDict
, соответственно.
Если я получаю значение из заданного keyPath, затем задаю его снова, используя тот же самый путь ключа, почему я получаю NSUnknownKeyException
?
Я знаю, что все мои словари являются изменяемыми.
-(void) postChangesFromPrevDict:(NSMutableDictionary *)prevDictionary
usingKeyPath:(NSString *)keyPath
{
NSArray *keys = [prevDictionary allKeys];
for (NSString *key in keys) {
id obj = [prevDictionary objectForKey:key];
NSString *newPath = [keyPath stringByAppendingString:[NSString stringWithFormat:@".%@",key]];
if ([obj isKindOfClass:[NSDictionary class]])
[self postChangesFromPrevDict:obj usingKeyPath:newPath];
else {
NSString *curStr = obj;
NSString *newStr = [self valueForKeyPath:newPath];
//debug breakpoint
if (![newStr isEqualToString:curStr]) {
@try {
[self setValue:newStr forKeyPath:newPath];
}
@catch (NSException *__unused exception) {
NSLog(@"Can't set key on %@",newPath);
}
}
}
}
}
PS: Чтобы пройти курс, я проверяю класс NSDictionary
, что хорошо, так как NSMutableDictionary
является его подклассом.