更改对象从 NSUserDefaults 获取
change object get from NSUserDefaults
我想更改从 NSUserDefaults 获取的对象。
但是在执行以下代码时,应用程序崩溃并显示错误消息:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object’
我有这个代码。
NSUserDefaults* pref = [NSUserDefaults standardUserDefaults];
NSMutableArray* data = [[NSMutableArray alloc]init];
data = [[pref objectForKey:@"Data"] mutableCopy];
for (NSArray* array in data) { //make object mutable
[array mutableCopy];
for (NSDictionary* dic in array) {
[dic mutableCopy];
}
}
[data[0][1] setObject:@"YES" forKey:@"isChecked"]; //for example
[pref setObject: data forKey: @"Data"];
[pref synchronize];
数据结构:
NSMutableArray* arr1 = [@[[@{@"name":@"abc", @"isChecked":@"YES"} mutableCopy], [@{@"name":@"def", @"isChecked":@"NO"} mutableCopy]] mutableCopy];
NSMutableArray* arr2 = [@[[@{@"name":@"ghi", @"isChecked":@"NO"} mutableCopy], [@{@"name":@"jkl", @"isChecked":@"YES"} mutableCopy]] mutableCopy];
NSMutableArray* data = [@[arr1, arr2] mutableCopy];
[userDefaults setObject: data forKey: @"Data"];
如何修复它以更改 NSArray
或 NSDictionary
从 NSUserDefaults
获取的对象?
你的想法是正确的 - 从 NSUserDefaults
返回的对象是不可变的,你需要使用 mutableCopy
来获取可变副本。但是,您的实施存在缺陷。
mutableCopy
returns 对象的新的可变副本。它不会使现有对象可变。您只是忽略了您正在创建的可变副本。
因为你想改变数组中的数据,你不能使用枚举,否则你会得到一个错误,指出枚举时对象被改变了,所以你需要通过索引访问数组 -
NSUserDefaults* pref = [NSUserDefaults standardUserDefaults];
NSMutableArray* data = [[pref objectForKey:@"Data"] mutableCopy];
for (int i=0;i<data.count;i++) {
NSMutableArray *mArray = [data[i] mutableCopy];
for (int j=0;j<mArray.count;j++) {
NSMutableDictionary *mDictionary=[mArray[j] mutableCopy];
mDictionary[@"SomeKey"]=@"SomeValue";
mArray[j]=mDictionary;
}
data[i]=mArray;
}
[userDefaults setObject: data forKey: @"Data"];
[array mutableCopy]
将创建数组的可变副本并 returns 它。您不会再次将其分配给变量。我想这将解决您的问题。
array = [array mutableCopy];
类似
dic = [dic mutableCopy];
我想更改从 NSUserDefaults 获取的对象。
但是在执行以下代码时,应用程序崩溃并显示错误消息:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object’
我有这个代码。
NSUserDefaults* pref = [NSUserDefaults standardUserDefaults];
NSMutableArray* data = [[NSMutableArray alloc]init];
data = [[pref objectForKey:@"Data"] mutableCopy];
for (NSArray* array in data) { //make object mutable
[array mutableCopy];
for (NSDictionary* dic in array) {
[dic mutableCopy];
}
}
[data[0][1] setObject:@"YES" forKey:@"isChecked"]; //for example
[pref setObject: data forKey: @"Data"];
[pref synchronize];
数据结构:
NSMutableArray* arr1 = [@[[@{@"name":@"abc", @"isChecked":@"YES"} mutableCopy], [@{@"name":@"def", @"isChecked":@"NO"} mutableCopy]] mutableCopy];
NSMutableArray* arr2 = [@[[@{@"name":@"ghi", @"isChecked":@"NO"} mutableCopy], [@{@"name":@"jkl", @"isChecked":@"YES"} mutableCopy]] mutableCopy];
NSMutableArray* data = [@[arr1, arr2] mutableCopy];
[userDefaults setObject: data forKey: @"Data"];
如何修复它以更改 NSArray
或 NSDictionary
从 NSUserDefaults
获取的对象?
你的想法是正确的 - 从 NSUserDefaults
返回的对象是不可变的,你需要使用 mutableCopy
来获取可变副本。但是,您的实施存在缺陷。
mutableCopy
returns 对象的新的可变副本。它不会使现有对象可变。您只是忽略了您正在创建的可变副本。
因为你想改变数组中的数据,你不能使用枚举,否则你会得到一个错误,指出枚举时对象被改变了,所以你需要通过索引访问数组 -
NSUserDefaults* pref = [NSUserDefaults standardUserDefaults];
NSMutableArray* data = [[pref objectForKey:@"Data"] mutableCopy];
for (int i=0;i<data.count;i++) {
NSMutableArray *mArray = [data[i] mutableCopy];
for (int j=0;j<mArray.count;j++) {
NSMutableDictionary *mDictionary=[mArray[j] mutableCopy];
mDictionary[@"SomeKey"]=@"SomeValue";
mArray[j]=mDictionary;
}
data[i]=mArray;
}
[userDefaults setObject: data forKey: @"Data"];
[array mutableCopy]
将创建数组的可变副本并 returns 它。您不会再次将其分配给变量。我想这将解决您的问题。
array = [array mutableCopy];
类似
dic = [dic mutableCopy];