0

在我的课堂上,我有两个数据对象:“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”——其中“key”值是“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的子类也是如此。

4

0 回答 0