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