更改对象从NSUserDefaults获取

时间:2015-03-05 07:25:55

标签: ios objective-c nsmutablearray nsuserdefaults nsmutabledictionary

我想从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"];

如何修改它以更改NSArrayNSDictionary来自NSUserDefaults的对象?

2 个答案:

答案 0 :(得分:5)

您有正确的想法 - 从NSUserDefaults返回的对象是不可变的,您需要使用mutableCopy来获取可变副本。但是,您的实施存在缺陷。

mutableCopy返回一个新的,可变的对象副本。它不会使现有对象变得可变。您只是忽略了您正在创建的可变副本。

由于你想要改变数组中的数据,你不能使用枚举,否则你会在枚举时得到一个错误的对象被突变,所以你需要通过索引来访问数组 -

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"];

答案 1 :(得分:0)

[array mutableCopy]将创建数组的可变副本,返回。您没有再次将其分配给变量。这将解决你的问题。

array = [array mutableCopy];

类似地

dic = [dic mutableCopy];