NCSFDictionary,Mutating方法发送到不可变对象

时间:2010-12-01 20:38:29

标签: objective-c nsmutabledictionary

我刚刚开始进入Objective-C的领域,并且慢慢地完成了这一切。我一直在努力解压缩一个NSMutableArray文件,然后在我的模型中用该数组初始化。该数组充满了各种NSMutableDicationary。从我所看到的将它添加为不可变的字典,所以我继续复制常规并将它们放入一个可变的并删除旧的。这个解决方案似乎适用于除第一个之外的每个实例。

我不知道为什么它会对除了第一个之外的所有人起作用。

以下是我如何初始化

-(id) initWithList:(NSMutableArray *)savedList
{
    self = [super init];
    if (self)
    {
        int size=0;
        serverList=[[NSMutableArray alloc] initWithArray:savedList copyItems:YES];
        size=[serverList count];
        for(int i=0;i<size;i++)
        {
            loginList=[NSMutableDictionary dictionaryWithDictionary:[serverList objectAtIndex:i]];
            [serverList addObject:loginList];
            [serverList removeObjectAtIndex:i];
        }
    }
    return self;
} 

以下是抛出错误的代码,该值正在从tableview中的复选框中读取并传递到此处以更改该值。

-(void)setMount:(int)row value:(NSNumber*)boolAsNumber
{
    [[serverList objectAtIndex:row] setObject:boolAsNumber forKey:@"mountshare"];
}

以下是我尝试更改第一个元素时显示的错误

2010-12-01 13:38:54.445 Network Share[35992:a0f] *** -[NSCFDictionary setObject:forKey:]: mutating method sent to immutable object

感谢您的帮助。如果有更好的方法请告诉我。

2 个答案:

答案 0 :(得分:3)

此循环代码错误:

    size=[serverList count];
    for(int i=0;i<size;i++)
    {

        loginList=[NSMutableDictionary dictionaryWithDictionary:[serverList objectAtIndex:i]];
        [serverList addObject:loginList];
        [serverList removeObjectAtIndex:i];
    }

删除对象时,数组将重新编号。在索引0处理完第一个对象后,原始第二个对象将成为索引0处的第一个对象,但i现在设置为索引1,这是原始第三个对象所在的位置!这意味着您只处理原始数组中的备用项目,而第2,第4等项目永远不会被交换,这就是您遇到错误的原因。

解决此问题的一种方法是将objectAtIndex:removeObjectAtIndex:调用中的“i”替换为“0”,这样您就可以将数据从数组前面取出。< / p>

备用解决方案是创建一个单独的newServerList数组并将新对象插入其中。在循环结束时,释放旧的serverList并将变量设置为指向newServerList。

答案 1 :(得分:1)

你的索引搞砸了。一旦你删除索引0处的对象,下一个将取而代之,你永远不会替换它,因为你继续使用索引1。

{immutable0, immutable1}

i = 0: 

addObject:
{immutable0, immutable1, mutable0}

removeObjectAtIndex:
{immutable1, mutable0}

i = 1:

addObject:
{immutable0, mutable0, mutable02}

removeObjectAtIndex:
{immutable0, mutable02}

- &GT;仍然有不变的那里。切记永远不要从同时循环的可变数组中删除对象。

您可以稍微压缩一下代码:

NSMutableArray *serverList = [NSMutableArray arrayWithCapacity:[savedList count]];
for (NSDictionary *dictionary in savedList)
{
  mutable = [dictionary mutableCopy];
  [serverList addObject:mutable];
  [mutable release];
}

与您的问题无关:如果您期望在那里存在不可变数组,那么该参数显然是错误的(NSMutableArray);如果以这种方式创建serverList,则不需要深层复制(copyItems:YES)。