2015-04-16 48 views
2

我有一個NSMutableSet集合,其中包含作爲SKNode的子類的自定義對象。我正在製作一個遊戲,將這些對象添加到NSMutableSet中並從中移除。我正在從主線程添加和刪除,所以線程化不是問題。出於某種原因,有時不能刪除對象,因爲找不到它。下面的方法返回NO爲什麼NSMutableSet不能刪除其中包含的對象?

[self.set containsObject:object] 

我看着這個問題並打印對象的地址和散列數量和NSMutableSet所有對象,果然出現在集合。

如果地址和散列號相等,可能是沒有找到對象的原因是什麼?我知道containsObject方法使用isEqual來比較這兩個值。

+0

** [self.set containsObject:object] **方法不可能刪除對象,可能是您正在傳遞對象引用,並且經過一段時間後,由於內存問題或ARC對象被刪除,所以當你試圖通過[self.set containsObject:object]得到它時可能找不到它。 –

+0

什麼'member:'return? – bgoers

+0

哦,我不是說[self.set containsObject:object]移除了這個對象。我首先嚐試了[self.fireSet removeObject:fire],但它沒有刪除該對象,因此我檢查了是否首先包含該對象。我正在使用ARC,但不應該釋放該對象,因爲我在NSMutableSet中看到它。 –

回答

2

hash結果必須是等於isEqual:其結果必然是YES。只匹配散列是不夠的。你有沒有檢查過isEqual:?默認isEqual:比較對象標識,而不是hash。允許集合使用hash來加速比較,但這只是一種優化。如果兩個對象返回YESisEqual:,它們也必須返回相同的hash,但反過來是不正確的。

+0

謝謝,我檢查了isEqual:遍歷集合,我找到了一個匹配。這很奇怪,因爲這發生在[self.set containsObject:object]之後,對於同一個對象返回NO! –

+0

這表明「isEqual:」是非確定性的(在某些情況下返回YES,在其他情況下返回NO),或者你的hash不遵循規則,有時爲相等的對象返回不同的值。一個簡單的測試就是讓'hash'在所有情況下返回1(這總是合法的哈希)。 –

+0

我打印出散列的情況下[自我。set containsObject:object]返回NO,並且在我的迭代中isEqual返回YES的情況下它們是相等的,這不應該足夠嗎? –

4

要使用對象作爲NSSet的元素,NSDictionary的鍵等,他們需要實現散列方法和isEqual:方法。如果你沒有自己的實現,hash返回對象指針,isEqual比較對象指針,一切都會正常工作。

如果你實現了hash和isEqual:你自己,你必須確定兩件事情:1.散列值和isEqual的結果在對象位於集合中時最不會改變(改變一個NSMutableString存儲在NSSet將是一個非常糟糕的主意)。 2.散列和isEqual:必須一致:兩個比較相等的對象必須返回相同的散列值。

+0

我還沒有實現這兩個方法,因爲我檢查了散列值並且它存在於NSSet中,所以如果遍歷整個集合,則isEqual返回YES。 –

相關問題