2015-08-08 50 views
0

我一直在試圖弄清楚這一段時間,我不完全清楚爲什麼或如何工作。爲什麼NSStrings的NSArray作爲NSMutableDictionary的關鍵字?

我需要存儲一對標識符(單獨,所以它們不能被連接在一起),該地圖中的對象。最初,我爲此使用了一個頂級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會很好,我只是想確保事情按我認爲的方式工作,並且這不是某種奇怪的未定義的行爲或某事。無論「鑰匙」你用一個鍵/值輸入到字典

+1

'NSArray'實現深平等:它發送的isEqual':'到每個元件,它們相對於其他陣列的元件。如果self的每個元素等於第二個數組中相應位置的元素,則返回YES,否則(或者如果兩個數組的計數不相同)則返回NO。散列與這種行爲是一致的(相等的數組必須具有相同的哈希),並且'NSArray'也可以複製,所以沒有理由爲什麼一串字符串不能用作關鍵字。 –

+0

就我個人而言,我不會依賴它,特別是如果你的每個鍵都有相同的散列值(數組數)。這可能會給你一組嚴重不平衡的桶。 –

回答

1

將散列並用作內部真正的關鍵。在使用Array作爲鍵時必須非常小心,因爲它會對其進行任何修改,其哈希將會更改,因此您將無法再訪問該值。

要回答你的問題,它的工作原理,因爲密鑰(NSArray的)進行散列。它是如何工作的:因爲存儲的「key」是NSArray的哈希,而不是數組本身(出於性能和存儲大小的原因)。 當您使用NSString作爲鍵時,它會執行相同的操作並在內部存儲字符串的散列。

相關問題