-[__ NSCFDictionary setObject:forKey:]:发送给不可变对象的变异方法从NSUserDefaults返回然后获取

时间:2018-07-02 15:00:00

标签: ios objective-c nsuserdefaults

以下代码将返回异常,并显示以下错误消息,并且我的应用程序已崩溃,在我的代码中,所有数据都存储在NSMutableDictionary中,然后存储在NSUserDefaults中 获取数据并分配全局NSMutableDictionary后,我将尝试在NSMutableDictionary应用崩溃时显示数据并显示错误

  

-[__ NSCFDictionary setObject:forKey:]:发送给不可变对象的变异方法

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary * cacheUploadDataDic = [[defaults objectForKey:@"SalaryIncomeData"] mutableCopy];

3 个答案:

答案 0 :(得分:0)

确切地说,它因可变类型问题而崩溃,从用户默认值检索的所有对象都是不可变的,它使用plist文件将数据列表序列化到文件,请查阅plist编程指南以了解受支持的类型。

您应将用户默认值视为简单的plist文件存储包装器。

改用NSMutableDictionary的'initWithDictionary:'方法。

答案 1 :(得分:0)

由于似乎我的评论中的问题没有答案,所以我只是大步走出去,猜测您的cacheUploadDataDic词典中包含更多NSDictionary对象中的任何对象,并且当您尝试更改这些词典之一时就会发生崩溃。之所以失败是因为mutableCopy执行了 shallow复制; 仅复制了字典对象本身,而保留了字典中 内的所有对象,包括任何其他字典。他们原来的一成不变的自我。

您可以通过制作字典的深层副本来解决此问题。有几种方法可以执行此操作,但最简单的方法可能是使用CFPropertyListCreateDeepCopy函数。不幸的是,我们必须进行一些桥接,因为该API仅在CoreFoundation级别可用,其原因之一就是这些永恒的谜团。

无论如何,请执行以下操作:

NSDictionary *dict = [[NSUserDefaults standardUserDefaults] objectForKey:@"SomeKey"];

NSMutableDictionary *mutableDict = CFBridgingRelease(
    CFPropertyListCreateDeepCopy(kCFAllocatorDefault,
                                 (__bridge CFDictionaryRef)dict,
                                 kCFPropertyListMutableContainersAndLeaves)
);

您现在可以将mutableDict的内容更改为您内心的内容。

答案 2 :(得分:-2)

按照您的代码显示,没有问题。
然后,如果可能,您可以在更新数据之前和之后cacheUploadDataDic检查NSMutableDictionary * cacheUploadDataDic = [[defaults objectForKey:@"SalaryIncomeData"] mutableCopy]的类。
如果有一个NSMutableDictionary,另一个是NSDictionary,则必须在另一行更改cacheUploadDataDic
如果找不到更改对象的位置,则可以尝试KVO。