由于尝试写入我认为是可变字典的内容,当我重新进入 TableViewController 时崩溃

Crash when I re-enter a TableViewController due to an attempt to write to what I think is a mutable dictionary

我创建了以下嵌套的 mutable 字典并将其保存到 NSUSerDefaults

self.configDict is {
    objectsDict =     {
        "40E1507D" =         {
            lastUpdate = "2015-05-30 05:02:40 +0000";
            subObjects =             {
                "D84EA15E" =                 {
                    lastUpdate = "2015-05-30 05:02:40 +0000";
                    show = 1;
                    title = subObjectOne;
                };
                "F20047D4" =                 {
                    lastUpdate = "2015-05-30 05:02:40 +0000";
                    show = 1;
                    title = GreenObject;
                };
            };
            title = Default;
        };
        "9EE82B8F" =         {
            lastUpdate = "2015-05-30 05:02:40 +0000";
            subObjects =             {
                "AEF3F442" =                 {
                    lastUpdate = "2015-05-30 05:02:40 +0000";
                    show = 1;
                    title = YellowObject;
                };
            };
            title = Other;
        };
    };
    lastUpdate = "2015-05-30 05:02:40 +0000";
    showAllObjects = 1;
}

在我的 table 视图控制器中,当我第一次进入它 (viewDidLoad) 时,我会这样加载 NSUserDefaults

self.configDict = [[defaults objectForKey:@"Config"] mutableCopy];

在我的.h中,我的字典定义如下:

@property (strong, nonatomic) NSMutableDictionary *configDict;

然后我继续更新其中的一些字段,比如上次更新时间:

NSMutableDictionary *subObjectDict = objectsDict[@"40E1507D"][@"subObjects"][@"D84EA15E"];
subObjectDict[@"lastUpdate"] = [NSDate date];

这一切都很好,我用

结束了
[[NSUserDefaults standardUserDefaults] synchronize];

当我退出 table 视图控制器并重新进入时发生崩溃。上面的代码如上所述重新执行,但是一旦我点击语句:

subObjectDict[@"lastUpdate"] = [NSDate date];

它因以下错误而崩溃: 2015-05-29 22:53:30.029 myApp[12837:128350] * 由于未捕获的异常 'NSInternalInconsistencyException' 而终止应用程序,原因:'-[__NSCFDictionary setObject:forKey:]: 发送到 immutable 对象的变异方法' * 首先抛出调用堆栈:

是不是因为我有嵌套字典,mutable拷贝没有进行深拷贝?为什么当我从 NSUserDefaults 中读取字典时它第一次工作,但是当我重新输入 TVC 时它崩溃了。

您在最外层的字典上使用 mutableCopy,但这不会使内部字典可变 - 它们仍然是不可变的字典,因为那是 NSUserDefaults 返回的内容。

我的猜测是,第一次通过您的代码时,子词典不存在或为零 - 如果没有看到更多代码,很难说。不管异常方法是多么清楚——你正试图改变一个不可变对象,所以你需要先制作一个可变副本。