更改对象从 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"];

如何修复它以更改 NSArrayNSDictionaryNSUserDefaults 获取的对象?

你的想法是正确的 - 从 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];