在我的课堂上,我有两个数据对象:'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
和{{ 1}}。
如果我从给定的keyPath获得了一个值,然后使用该SAME密钥路径再次进行设置,为什么我会得到dataDict
?
我确实知道我所涉及的所有字典都是可变的。
NSUnknownKeyException
PS:为递归,我测试了一个-(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);
}
}
}
}
}
类,因为NSDictionary
是其子类。