Ios 合并字典-不兼容类型错误

Ios 合并字典-不兼容类型错误,ios,objective-c,nsdictionary,Ios,Objective C,Nsdictionary,我已经试着合并两本词典好几个小时了。搜索发现我可以使用[NSMutableDictionary addEntriesFromDictionary: NSDictionary *areaAttributes = [[area entity] attributesByName]; NSDictionary *gpsAttributes = [[gps entity] attributesByName]; NSMutableDictionary *areaAttributes

我已经试着合并两本词典好几个小时了。搜索发现我可以使用
[NSMutableDictionary addEntriesFromDictionary:

    NSDictionary *areaAttributes = [[area entity] attributesByName];
    NSDictionary *gpsAttributes = [[gps entity] attributesByName];

    NSMutableDictionary *areaAttributesM = [areaAttributes mutableCopy];
    NSMutableDictionary *gpsAttributesM = [gpsAttributes mutableCopy];

    NSMutableDictionary *combinedAttributes =  [areaAttributesM addEntriesFromDictionary:gpsAttributesM];
但我得到了一个错误:

Initializing 'NSMutableDictionary *_strong' with an expression of incompatible type 'void'

这意味着
[areaAttributesM addEntriesFromDictionary:gpsatAttributesM]
返回
void
?我的理解正确吗?为什么它会返回void?

是的,你是对的。发件人:

至于原因,这很简单:在Cocoa中改变对象的函数通常返回void,因此您可以很容易地将它们与返回不同对象的函数区分开来

而且,没有理由
mutableCopy
gpsAttributesdictionary;它只是用作
-[addEntriesFromDictionary:
的参数,它不需要是可变的

因此,正确的方法是:

NSDictionary *areaAttributes = [[area entity] attributesByName];
NSDictionary *gpsAttributes = [[gps entity] attributesByName];

NSMutableDictionary *combinedAttributes = [areaAttributes mutableCopy];
[combinedAttributes addEntriesFromDictionary:gpsAttributes];
如果经常执行以下操作,您可能希望将其封装在函数(或
NSDictionary
上某个类别中的方法)中:

NSDictionary *mergeDictionaries(NSDictionary *lhs, NSDictionary *rhs) {
    NSMutableDictionary *ret = [lhs mutableCopy];
    [ret addEntriesFromDictionary:rhs];
    return ret;
}

从文档中,addEntriesFromDictionary告诉我们:

如果两个字典包含相同的键,则接收字典的该键的前一个值对象将发送一条释放消息,新的值对象将取代它。 您需要使用setObject将每个对象添加到字典中。您需要循环一个字典的键并将其添加到最终的字典中

即使是setObject也告诉我们同样的道理:

价值的关键。已复制密钥(使用copyWithZone:;密钥必须符合NSCopying协议)。如果字典中已经存在aKey,则另一个对象将取代它。 字典中不能有两个相同的键。字典中的所有键都是唯一的

如果仍希望在字典中具有相同的键值,则必须使用不同的键

例如,您有两个具有以下值的词典:

NSDictionary *dict1=@{@"hello":@"1",@"hello2" :@"2"};
NSDictionary *dict2=@{@"hello":@"1",@"hello2":@"2",@"hello3":@"1",@"hello6":@"2",@"hello4":@"1",@"hello5" :@"2"};

 NSMutableDictionary *mutableDict=[NSMutableDictionary dictionaryWithDictionary:dict1];
    for (id key in dict2.allKeys){
        for (id subKey in dict1.allKeys){
            if (key==subKey) {
                [mutableDict setObject:dict2[key] forKey:[NSString stringWithFormat:@"Ext-%@",key]];
            }else{
                [mutableDict setObject:dict2[key] forKey:key];
            }
        }
    }
循环结束时,新的可变字典将具有以下键值:

{
    "Ext-hello" = 1;
    "Ext-hello2" = 2;
    hello = 1;
    hello2 = 2;
    hello3 = 1;
    hello4 = 1;
    hello5 = 2;
    hello6 = 2;
}
如您所见,hello和hello2键被重命名为Ext-hello1,Ext-hello2。形成dict1,您仍然将所有dict2值添加到可变dict中

如果不想添加新键,则可以将值添加到arrya中,并将该数组添加到字典中。可以将for循环修改为:

for (id key in dict2.allKeys){
    for (id subKey in dict1.allKeys){
        if (key==subKey) {
            NSMutableArray *myArr=[[NSMutableArray alloc]init];
            [myArr addObject:dict1[subKey]];
            [myArr addObject:dict2[key]];
            [mutableDict setObject:myArr forKey:key];
        }else{
            [mutableDict setObject:dict2[key] forKey:key];
        }
    }
}
现在将这些值合并到一个数组中:

{
    hello =     (
        1,
        1
    );
    hello2 = 2;
    hello3 = 1;
    hello4 = 1;
    hello5 = 2;
    hello6 = 2;
}

这样,键的数量将相同,相同键的值将作为一个数组添加。

[combinedAttributes addEntriesFromDictionary:GPSATAttributes]
给了我这个错误:
由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“没有为此NSKnownkeyDictionary定义键“纬度”
纬度
gpsAttributes
中的键。
addEntriesFromDictionary
是否应该将此键添加到
areaAttributes
?啊,您不是在处理常规字典,而是使用未记录的
NSKnownkeyDictionary
处理具有固定键集的字典。这是一个单独的问题…但我看到你写了一个单独的问题,所以我会在那里回答。
{
    hello =     (
        1,
        1
    );
    hello2 = 2;
    hello3 = 1;
    hello4 = 1;
    hello5 = 2;
    hello6 = 2;
}