我创建了一个简单的数据库并放入了NSUserDefaults。我的数据库是NSMutableArray,里面有字典和数组。当我从NSUSerDefaults创建NSMutableArray时,我无法向NSMutableArray中的可变对象添加任何对象。这是我的代码:
NSMutableArray *arrayOne = [NSMutableArray arrayWithContentsOfFile:[self createEditableCopyOfIfNeededWithFileName:@"Form.plist"]];
NSUserDefaults *ayarlar = [NSUserDefaults standardUserDefaults];
[ayarlar setObject:arrayOne forKey:@"form"];
NSMutableArray *arrayTwo = [NSMutableArray arrayWithArray:[[ayarlar objectForKey:@"form"] mutableCopy]];
[[[arrayTwo objectAtIndex:0] objectForKey:@"itemlar"] addObject:@"hop"];
这是错误:
'NSInternalInconsistencyException',原因:' - [__ NSCFArray insertObject:atIndex:]:发送到不可变对象的变异方法'
我该如何使这项工作?谢谢大家。
答案 0 :(得分:4)
NSUserDefaults不是存储数据的正确位置。首先,它应该只用于非常少量的数据,例如设置。其次,它总是返回不可变对象,即使你设置了可变对象。制作第一个数组的可变副本没有用,因为只有数组才是可变的。
中,mutableCopy方法没有触及该数组内部的所有内容。您应该使用NSPropertyListSerialization类从文件中读取和写入数据。在阅读时,您可以传递控制读取对象的可变性的选项。在那里,您需要传递NSPropertyListMutableContainers或NSPropertyListMutableContainersAndLeaves。
首先,所有容器(数组和字典)都是可变的。对于后者,叶子(即NSString和NSData对象)也是可变的。
根据数据集的大小,您可能应该使用真实数据库或核心数据。
答案 1 :(得分:2)
NSUserDefaults
永远不会返回可变对象。
你的代码正在执行创建你能想到的可变数组的各种方式(即你正在创建一个你刚刚创建的可变副本的可变副本),但是,你只处理根容器项 - 不是内/叶项目。所以,当你在可变数组上执行objectForKey:@"itemlar"]
时,你会得到一个不可变对象。
为了使它工作,你需要编写自己的方法,通过在所有级别创建可变副本的数组进行迭代和递归。
或者,您可以查看this之类的第三方选项,它会在NSUserDefaults
的引擎下挖掘,以生成可变容器。
答案 2 :(得分:2)
NSUserDefaults
和一般的属性列表不记录可变性。当从文件重新创建对象时,它可以构造为可变对象或不可变对象(对于具有该选项的类型,例如数组)。遗憾的是,NSUserDefaults
没有为您提供API调用以直接获取不可变对象。
您有两个选项:(a)创建NSUserDefaults
返回的对象的可变副本,或者(b)将对象自己存储为单独文件中的属性列表 - 这样您就可以将其读回直接变异。
对于(b)阅读Apple's docs - 它显示了如何处理可变性。
答案 3 :(得分:1)
您可以使用方法insertObject
直接执行。
取代
[[[arrayTwo objectAtIndex:0] objectForKey:@"itemlar"] addObject:@"hop"];
使用此,
[arrayTwo insertObject:@"hop" atIndex:0];
这样就可以了,因为我已经测试过它也是有效的,因为你可以将它作为NSARRAY
的不可变对象并保存到NSUSERDEFAULTS
。