-[__NSCFDictionary setObject:forKey:]:向不可变对象发送了可变方法

4
运行下面的代码时,[dict setValue:@"null" forKey:@"name"]; 会一直崩溃。我在这里搜索并找到其他帖子是由于人们没有使用 NSMutableDictionary 导致的。然而,我正在使用此功能。
如果 namenull,为什么会在这一行崩溃?
NSMutableArray *tempCustomers = [[NSMutableArray alloc] init];
for (NSMutableDictionary *dict in [[json objectForKey:@"data"] mutableCopy]) {
    if ([dict objectForKey:@"name"] == [NSNull null]) {
        [dict setValue:@"null" forKey:@"name"];
    }
    [tempCustomers addObject:dict];
}

2
也许mutableCopy并不是“deepMutableCopy”,我的意思是,你只是枚举了可变对象,但是这个集合中的对象并不是可变的? - BergP
2
你正在使用一个可变字典的不可变对象。 - nielsbot
3个回答

15

我最终使用了这个。我猜这就是所谓的deepMutableCopy?

NSMutableArray *tempCustomers = [[NSMutableArray alloc] init];
for (NSMutableDictionary *dict in [[json objectForKey:@"data"] mutableCopy]) {
    if ([dict objectForKey:@"name"] == [NSNull null]) {
        NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
        tempDict = [dict mutableCopy];

        [tempDict setValue:@"null" forKey:@"name"];
        [tempCustomers addObject:tempDict];
    } else {
        [tempCustomers addObject:dict];
    }
}

这大致相当于深度可变复制 - 基本上,你需要一个dict的可变副本,而不仅仅是JSON对象数据的可变副本。你试图修改的每个字典本身都是不可变的,尽管原始字典集合通过你的mutableCopy变得可变。(术语“深度复制”指的是所有包含的数据结构的递归复制,而不仅仅是顶层。) - Tim
没错。您会获得JSON数据的可变副本(其中仍包含不可变字典),然后您会创建每个字典的可变副本 - 这近似于“深度可变副本”,即使它不在单独的方法中。 - Tim

2
也许mutableCopy并不是“深度可变复制”,我的意思是,你只是枚举可变对象,但是这个集合中的对象并不是可变的(引用我的评论)。

0
创建新数组[[NSMutableArray alloc]initWithArray:[json objectForKey:@"data"]]并在for循环中使用它。
不要使用[json objectForKey:@"data"],改为使用新的数组。代码应该如下所示:
NSMutableArray *tempCustomers = [[NSMutableArray alloc] init];
NSMutableArray *search = [[NSMutableArray alloc]initWithArray:[json objectForKey:@"data"]];
for (NSMutableDictionary *dict in search)
{
    if ([dict objectForKey:@"name"] == [NSNull null])
    {
        [dict setValue:@"null" forKey:@"name"];
    }
    [tempCustomers addObject:dict];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接