我有两个名为“dict”和newdict的NSMutableDictionary对象。然后尝试将newdict分配给“myfield1”字段。但是,我正面临一个错误。
NSMutableDictionary *dict = @{ @"myfield1" : @{ @"subfield1" : @"mysubfield1" ,
@"subfield2" : @"mysubfield2" },
@"myfield2": @"myfield2",
@"myfield3": @"myfield3"};
NSMutableDictionary *newdict = @{ @"subfield1" : @"mynewsubfield1" ,
@"subfield2" : @"mynewsubfield2" };
[dict setValue:newdict forKey:@"myfield1"];
错误:
*** Terminating app due to uncaught exception 'NSUnknownKeyException',
reason: '[<__NSDictionaryI 0x17db3bb0> setValue:forUndefinedKey:]:
this class is not key value coding-compliant for the key loc.'
我该如何解决这个问题?
答案 0 :(得分:5)
不要使用setValue:forKey:
,因为这是KVC方法,而不是字典方法。使用setObject:forKey:
。从技术上讲,KVC方法可行,但通常只有在有特殊需要时才能使用它。
您真正的问题是您的字典实例不可变。使用mutableCopy
从文字定义创建可变版本。文字定义总是不可变的。
答案 1 :(得分:1)
正如@Wain所解释的那样,你的字典实例不可变。
您可能会感到困惑的是,您将变量声明为NSMutableDictionary
,因此您认为它们是可变的。但 @{ … }
字面语法等同于[NSDictionary dictionaryWithObjects:forKeys:count:
,因此创建(不可变)NSDictionary
实例。
您将此值影响到NSMutableDictionary
类型的变量的事实不会改变这一点,也不会使此字典神奇地变为可变。
这就是为什么@Wain正确建议使用mutableCopy
使NSDictionary
成为NSMutableDictionary
的原因,以便您可以在其上调用setValue:forKey:
或setObject:forKey:
。另一种方法是使用[NSMutableDictionary dictionaryWithDictionary:@{ … }];
来创建可变字典。
事实上,如果-Wincompatible-pointer-types
警告是开启的,默认情况下就是这种情况,那么你应该有warning: incompatible pointer types initializing 'NSMutableDictionary *' with an expression of type 'NSDictionary *'
之类的警告,这些警告应该会引导您进入问题的原因及其解决方案。 (总是阅读警告,这不是因为它们只是警告而且它们不会使编译失败,因为它们并不重要!)
答案 2 :(得分:1)
只需添加“mutableCopy”即可创建NSMutableDictionary类型的字典
NSMutableDictionary *dict = [@{ @"myfield1" : @{ @"subfield1" : @"mysubfield1" ,
@"subfield2" : @"mysubfield2" },
@"myfield2": @"myfield2",
@"myfield3": @"myfield3"} mutableCopy];
NSMutableDictionary *newdict = [@{ @"subfield1" : @"mynewsubfield1" ,
@"subfield2" : @"mynewsubfield2" } mutableCopy];
dict[@"myfield1"]=newdict;