2012-09-13 16 views
5

假設我有一個名爲Person的對象,它具有屬性socialSecurityNumber,並且此類重寫isEqual:方法以在社會安全號碼屬性相等時返回true。並說我已經將一堆Person的實例放入NSDictionaryNSDictionary的objectForKey:依賴於身份還是相等?

如果我現在實例化一個newPerson對象恰好具有相同的社會安全號碼作爲一個已經在字典中,和我做[myDictionary objectForKey:newPerson],將它使用isEqual:並返回YES,還是會比較指針並返回NO?

我知道我可以寫一個簡單的測試來找出,但我想了解objectForKey:究竟如何認定在字典中的比賽,一般是如何保持一致,這是跨越可可(即不NSArrayindexofObject:工作一樣嗎? )

回答

10

NSDictionary像散列表一樣工作。因此它使用-hash-isEqual:來查找字典中與給定鍵相對應的對象。

所以要回答你的問題NSDictionary,這使用isEqual:而不是指針比較。但是,除了isEqual:之外,您還應該在Person課程中執行hash,以使其工作。

字典內的關鍵值對被稱爲一個條目。每個條目由一個表示該鍵的對象和另一個爲該鍵的值的對象組成。在字典中,密鑰是唯一的。也就是說,單個字典中沒有兩個密鑰是相等的(由isEqual確定:)。

如果兩個對象是相等的,它們必須具有相同的哈希值。如果您在子類中定義isEqual:並且打算將該子類的實例放入集合中,則最後一點尤爲重要。確保你也在你的子類中定義了散列。

在索引0處開始,數組的每個元素被髮送的isEqual一個。此方法將anObject參數傳遞給每個isEqual:消息。如果isEqual對象被認爲是相等的:(在NSObject協議中聲明)返回YES。


您應該始終閱讀文檔:由上面引用的提取物中指出,這幾樣的細節在「討論」都被解釋或方法的文檔的「特殊考慮」部分或者在類文檔本身的「概述」部分。

+0

如何實現散列? –

+0

就像你喜歡的那樣,只要2個相同的哈希表具有相同的哈希值,並且哈希值不太複雜就無法計算。用於此的算法取決於您,但具有不同散列值的兩個對象將始終被視爲不同,並且具有相同散列值的兩個對象將被視爲可能相等,並將調用「isEqual:」以確保它們確實是平等的。這樣只通過比較散列值(只是整數)就可以非常快地進行比較和字典查找,並且只有當散列值相等時才與「isEqual:」進行實際比較。 – AliSoftware

+0

例如,對於字符串,可以通過返回字符串的長度來實現'hash'方法。兩個相等的字符串將具有相同的散列值,而2個不同的字符串將具有不同的散列值。一些不同的字符串(比如'@「bar」'和'@「baz」')仍然具有相同的散列值,但這不是問題,在這種情況下,'isEqual:'將會生成更深的分析字符字符來檢查平等。但是這種比較耗時的比較只能用來比較相同長度的字符串:不同長度的字符串會更快地返回「NO」。 – AliSoftware

1

如何一致的,這是整個可可(即不NSArray的indexofObject:工作一樣?)

是一致的,並在同一時間它不是。我的意思是有兩種方法可以使用:isEqualhash。你不應該太在意什麼時候使用。你應該關注的是尊重NSObject協議要求,並確保如果兩個對象根據isEqual相等,則它們也具有相同的散列。

isEqual documentation in the NSObject Protocol Reference

如果兩個對象是相等的,它們必須具有相同的哈希值。如果您在 子類中定義isEqual:並且打算將該子類的實例放入 集合中,則此最後一點尤其重要。確保你也在你的子類中定義了散列。

+0

兩條評論:一,NSArray有第二個方法「indexOfObjectIdenticalTo:」,它發現_same_對象,它是同一個對象指針。包含「foo」的兩個不同的NSString *對象將被視爲不同。二,散列和isEqual的默認實現:使用指針作爲散列鍵並比較指針。例如NSWindow/UIWindow可以用作字典中的鍵,指針必須是相同的。 – gnasher729

相關問題