Ошибка valueForKeyPath с вложенными объектами NSMutableDictionary - PullRequest
0 голосов
/ 19 декабря 2018

В моем классе у меня есть два объекта данных: 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 является его подклассом.

...