由于尝试写入我认为是可变字典的内容,当我重新进入 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
返回的内容。
我的猜测是,第一次通过您的代码时,子词典不存在或为零 - 如果没有看到更多代码,很难说。不管异常方法是多么清楚——你正试图改变一个不可变对象,所以你需要先制作一个可变副本。
我创建了以下嵌套的 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
返回的内容。
我的猜测是,第一次通过您的代码时,子词典不存在或为零 - 如果没有看到更多代码,很难说。不管异常方法是多么清楚——你正试图改变一个不可变对象,所以你需要先制作一个可变副本。