1

我创建了一个简单的数据库并放入 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:]:发送到不可变对象的变异方法'

我怎样才能使这项工作?谢谢大家。

4

4 回答 4

5

NSUserDefaults 不是存储数据的正确位置。首先,它应该只用于非常少量的数据,例如设置。其次,它总是返回不可变对象,即使您设置了可变对象。制作第一个数组的可变副本并没有帮助,因为只有数组是可变的。mutableCopy 方法不会触及该数组中的所有内容并保持不可变。

您应该使用 NSPropertyListSerialization 类从文件中读取和写入数据。在读取时,您可以传递控制读取对象可变性的选项。在那里你会想要传递 NSPropertyListMutableContainers 或 NSPropertyListMutableContainersAndLeaves。

首先,您的所有容器(即数组和字典)都将是可变的。对于后者,叶子(即 NSString 和 NSData 对象)也将是可变的。

根据您的数据集可以得到多大,您可能应该使用真实的数据库或 Core Data。

于 2013-06-01T19:05:52.147 回答
2

NSUserDefaults从不返回可变对象。

您的代码正在执行创建您可以想到的可变数组的所有方式(即,您正在创建您刚刚创建的可变副本的可变副本),但是,您只处理根容器项 - 而不是内部/叶子项目。因此,当您objectForKey:@"itemlar"]在可变数组上执行操作时,您将得到一个不可变对象。

为了使其工作,您需要编写自己的方法,在数组中迭代和递归,在所有级别创建可变副本。

或者,您可以查看像这样的第 3 方选项,它在引擎盖下挖掘NSUserDefaults以生成可变容器。

于 2013-06-01T19:04:55.130 回答
2

NSUserDefaults和一般的属性列表不记录可变性。当从文件重新创建对象时,它可以构造为可变或不可变对象(对于具有选项的类型,例如数组)。不幸的是NSUserDefaults,没有给你一个 API 调用来直接获取一个不可变对象。

您有两个选择是(a)创建由返回的对象的可变副本NSUserDefaults或(b)将对象自己作为属性列表存储在单独的文件中 - 这样您就可以直接将其读回为可变的。

对于 (b) 阅读Apple 的文档- 它显示了如何处理可变性。

于 2013-06-01T19:08:39.800 回答
0

可以直接使用 method 来做insertObject

代替

[[[arrayTwo objectAtIndex:0] objectForKey:@"itemlar"] addObject:@"hop"];

用这个,

[arrayTwo insertObject:@"hop" atIndex:0];

这将适用,因为我已经测试过它也可以正常工作,之后您可以将其设置为不可变对象NSARRAY并将其保存到NSUSERDEFAULTS.

于 2013-06-01T19:24:27.377 回答