我一直试图弄清楚这一点,我并不完全清楚这是为什么或如何运作。
我需要存储一对映射到对象的标识符(分开,因此它们不能连接在一起)。最初,我使用了顶级NSMutableDictionary实例,其下面嵌套了NSMutableDictionary对象。要检索标识符对的值,我可以调用:
[[myTopLevelDictionary objectForKey:key1] objectForKey:key2]
这样可以很好地工作,即使跟踪嵌套的NSMutableDictionary实例需要一些额外的工作。
昨天,我想知道是否有任何方法可以直接使用一对NSString对象作为密钥。所以我尝试用两个NSString对象创建一个NSArray实例,并将其作为密钥使用,并且它起作用了:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSArray *key = [NSArray arrayWithObjects:@"A", @"B", nil];
[dict setObject:@"foobar" forKey:key];
NSLog(@"%@", [dict objectForKey:key]);
NSLog(@"%@", [NSArray arrayWithObjects:@"A", @"B", nil];
// Even this seems to work?
NSMutableArray *key2 = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil];
[key2 removeLastObject];
NSLog(@"%@", key2);
所有三个案例都将成功打印" foobar"。如果我更改数组中NSString对象的顺序,则字典将返回nil。如果我再次添加或删除NSString对象,字典将正确返回nil。只有具有正确NSString对象的NSArray对象包含正确顺序的正确内容似乎才能检索到适当的值。
我的问题是......为什么这样做,以及如何运作?
我知道散列与它有关,但是向一个NSArray对象发送散列似乎只是返回了对象数,所以我无法想象它与它有很大关系。然后我想也许NSDictionary试图获得NSArray的描述并将其用作基于字符串的键,但我不确定如何测试这个理论,因为NSString的哈希不是和NSArray的哈希一样(所以我不能只使用复制[[NSArray arrayWithObjects:@"A", @"B", nil] description]
输出的NSString键。)
不要误会我的意思,如果我能像这样使用NSArray / NSString / NSMutableDictionary,那就太棒了,我只想确保事情按照我认为的方式运作,这样做不是某种奇怪的未定义行为或其他东西。
答案 0 :(得分:1)
用于输入字典的键/值的任何“键”都将被散列并在内部用作实键。使用数组作为键时必须非常小心,因为它对它进行了任何修改,它的哈希值会改变,因此你将无法再访问该值。
要回答您的问题,它可以正常工作,因为密钥(NSArray)可以进行哈希处理。它是如何工作的:因为存储的“密钥”是NSArray的散列,而不是数组本身(出于性能和存储大小的原因)。 当您使用NSString作为键时,它会执行相同操作并在内部存储字符串的哈希值。