使用方法setValue:forPath时,NSInternalInconsistencyException与NSUserDefaults在一起

问题描述

|| 我的代码如下:
NSMutableDictionary *configure = [[NSUserDefaults standardUserDefaults] objectForKey:@\"configure\"];
if (!configure){    
configure = [NSMutableDictionary dictionary];
[configure setValue:[NSMutableDictionary dictionary] forKeyPath:@\"select\"] ;

[configure setValue:[NSMutableDictionary dictionary] forKeyPath:@\"select.around\"];
[configure setValue: @\"All\" forKeyPath:@\"select.around.name\"];

[[NSUserDefaults standardUserDefaults] setObject:configure forKey:@\"configure\"];
[[NSUserDefaults standardUserDefaults] synchronize];
    }
NSString *keyPath = @\"configure.select.around\";
NSMutableDictionary *aroundConfigure = [[[NSUserDefaults standardUserDefaults] valueForKeyPath:keyPath] mutableCopy];
[aroundConfigure setObject:@\"\" forKey:@\"name\"];
[[NSUserDefaults standardUserDefaults] setValue:aroundConfigure forKeyPath:keyPath];
每次都崩溃,并显示以下错误:
** Terminating app due to uncaught exception \'NSInternalInconsistencyException\',reason: \'-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object\'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00daebe9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x00f035c2 objc_exception_throw + 47
    2   CoreFoundation                      0x00d67628 +[NSException raise:format:arguments:] + 136
    3   CoreFoundation                      0x00d6759a +[NSException raise:format:] + 58
    4   CoreFoundation                      0x00dad401 -[__NSCFDictionary setObject:forKey:] + 209
    5   Foundation                          0x0004b34d -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 399
    6   Foundation                          0x0004b34d -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 399
    7   Untitled                            0x00002429 -[UntitledAppDelegate application:didFinishLaunchingWithOptions:] + 774
    8   UIKit                               0x002b81fa -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
    9   UIKit                               0x002ba55e -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 439
    10  UIKit                               0x002c4db2 -[UIApplication handleEvent:withNewEvent:] + 1533
    11  UIKit                               0x002bd202 -[UIApplication sendEvent:] + 71
    12  UIKit                               0x002c2732 _UIApplicationHandleEvent + 7576
    13  GraphicsServices                    0x016e4a36 PurpleEventCallback + 1550
    14  CoreFoundation                      0x00d90064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    15  CoreFoundation                      0x00cf06f7 __CFRunLoopDoSource1 + 215
    16  CoreFoundation                      0x00ced983 __CFRunLoopRun + 979
    17  CoreFoundation                      0x00ced240 CFRunLoopRunSpecific + 208
    18  CoreFoundation                      0x00ced161 CFRunLoopRunInMode + 97
    19  UIKit                               0x002b9fa8 -[UIApplication _run] + 636
    20  UIKit                               0x002c642e UIApplicationMain + 1160
    21  Untitled                            0x00002100 main + 102
    22  Untitled                            0x00002091 start + 53
)
terminate called after throwing an instance of \'NSException\'
我知道ѭ2应该和可变的字典一起使用。将KVO与NSUserDefaults一起使用是否有问题?顺便说一下,我使用的平台是iPhone。     

解决方法

您的代码没有按照您认为的去做:
NSMutableDictionary *configure = [[NSUserDefaults standardUserDefaults] objectForKey:@\"configure\"];
这会将“ 4”设置为标准默认值,即键“ 4”的值
configure = [NSMutableDictionary dictionary];
这会将
configure
设置为一个新的空字典,而不是您从用户默认值获得的字典
[configure setValue:[NSMutableDictionary dictionary] forKeyPath:@\"select\"] ;
现在,您将一个空字典作为键“ 9”的值
[configure setValue:[NSMutableDictionary dictionary] forKeyPath:@\"select.around\"];
您正在为此键路径添加另一个空字典
[configure setValue: @\"All\" forKeyPath:@\"select.around.name\"];
您正在为此键路径设置一个字符串值
[[NSUserDefaults standardUserDefaults] setObject:configure forKey:@\"configure\"];
您现在正在将此奇数字典放入NSUserDefaults中
[[NSUserDefaults standardUserDefaults] synchronize];

NSString *keyPath = @\"configure.select.around\";

NSMutableDictionary *aroundConfigure = [[[NSUserDefaults standardUserDefaults] valueForKeyPath:keyPath] mutableCopy];
这只是一个空的可变字典
[aroundConfigure setObject:@\"\" forKey:@\"name\"];
您正在为此字典中的某些键设置一个空字符串
[[NSUserDefaults standardUserDefaults] setValue:aroundConfigure forKeyPath:keyPath];
然后将这个奇数字典设置为用户默认值。 这一切都很令人困惑。 您正在尝试做什么? 编辑添加 如果您已经“简化”了代码,那么我们就看不到它应该做什么。 您的应用程序崩溃是因为您尝试更改不可变的NSDictionary的键值对,而不是NSMutableDictionary。请参见跟踪的第6行。 由于您提供了“简化的”代码-我不知道您在哪里进行此操作。     ,今天我也遇到了这个问题,因为我正在像这样在字典中制作数据
NSMutableDictionary *Dic =[myMutableAry objectAtIndex:0];  
当我更新我的dic值时获取数据后崩溃   *由于未捕获的异常\'NSInternalInconsistencyException \'而终止应用程序,原因:\'-[__ NSCFDictionary   setObject:forKey:]:发送给不可变对象的变异方法' 经过大量研究,我确实找到了解决方案,所以只做一件事
NSMutableDictionary *Dic = [NSMutableDictionary dictionaryWithDictionary:[myMutableAry objectAtIndex:0]];
    ,您使用NSUserDefaults的方式是错误的,NSUserDefaults返回一个不可更改的字典。这就是这个问题的原因。因此,您必须从NSUserDefaults显式请求一个可变对象。请使用下面的代码行。
NSMutableDictionary *configure = [[[NSUserDefaults standardUserDefaults] objectForKey:@\"configure\"]mutableCopy];
与我一起工作。 谢谢你好运:)     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...