Ios 为什么';NSMutableSet是否删除其中包含的对象?

Ios 为什么';NSMutableSet是否删除其中包含的对象?,ios,objective-c,nsmutableset,Ios,Objective C,Nsmutableset,我有一个NSMutableSet集,其中包含作为SKNode子类的定制对象。我正在制作一个游戏,在这个游戏中,这些对象被添加到NSMutableSet中并从中移除。我正在主线程中添加和删除线程,因此线程不是问题。由于某些原因,有时无法删除对象,因为找不到它。以下方法返回NO: [self.set containsObject:object] 我研究了这个问题,打印了对象的地址和散列号,以及NSMutableSet中所有对象的地址和散列号,果然它出现在集合中 如果地址和散列数相等,则找不到对象的

我有一个
NSMutableSet
集,其中包含作为
SKNode
子类的定制对象。我正在制作一个游戏,在这个游戏中,这些对象被添加到NSMutableSet中并从中移除。我正在主线程中添加和删除线程,因此线程不是问题。由于某些原因,有时无法删除对象,因为找不到它。以下方法返回
NO

[self.set containsObject:object]
我研究了这个问题,打印了对象的地址和散列号,以及
NSMutableSet
中所有对象的地址和散列号,果然它出现在集合中


如果地址和散列数相等,则找不到对象的原因可能是什么?我知道
containsObject
方法使用比较这两个值的
isEqual

哈希的结果必须相等,
isEqual:
的结果必须是
YES
。仅仅匹配散列是不够的。您是否已选中isEqual:?默认的
isEqual:
比较对象标识,而不是
散列
<集合可以使用代码>哈希来加速比较,但这只是一种优化。如果两个对象为
isEqual:
返回
YES
,则它们还必须返回相同的
hash
,但反之不成立。

要将对象用作NSSet的元素、NSDictionary的键等,它们需要实现hash方法和isEqual:方法。如果您没有自己的实现,hash将返回对象指针,而isEqual将比较对象指针,一切都将正常工作


如果您自己实现了hash和isEqual,那么必须确保两件事:1。当对象在集合中时,哈希值和isEqual most的结果不会更改(更改存储在NSSet中的NSMutableString将是一个非常糟糕的主意)。2.哈希和isEqual:必须一致:比较相等的两个对象必须返回相同的哈希值

[self.set containsObject:object]方法不可能删除对象,可能是因为您正在传递对象引用,一段时间后,由于内存问题或弧,对象被删除,因此在您尝试通过[self.set containsObject:object]获取对象时可能找不到它。
成员:
返回什么?哦,我不是这个意思[self.set containsObject:object]删除该对象。我首先尝试了[self.fireSet removeObject:fire],但它没有删除该对象,因此我检查了该对象是否首先包含。我正在使用ARC,但不应释放该对象,因为我在NSMutableSet中看到它。如果转储该集的成员,然后执行
p(BOOL)[fire isEqual:0xnnnnn]
(其中0xnnnnn是集合中对象的地址),是真是假?感谢您的更正,[self.set containsObject:object]返回NO。成员返回nil。谢谢,我检查了isEqual:iterating遍历集合,找到了匹配项。这非常奇怪,因为这是在[self.set containsObject:object]为同一对象返回了否!这表明
isEqual:
是不确定的(在某些情况下返回
YES
,在其他情况下返回
NO
),或者您的
散列
不遵循规则,有时会为相等的对象返回不同的值。对此,一个简单的测试是使
散列
在所有情况下都返回1(这始终是合法的散列)。我打印了[self.set containsObject:object]情况下的散列返回否,并且它们是相等的,如果isEqual:在我的迭代中返回了YES,那还不够吗?哇,我按照您的建议做了,为我的所有对象哈希返回了1,并且非常确定[self.set containsObject:object]从未返回“否”。我想了解这是如何解决我的问题的,因为哈希值相等。无论如何,这个答案应该被投票表决!因为它解决了我的问题,谢谢。@RonenMichaelHarati,你的问题几乎可以肯定,哈希值与最初将对象添加到集合时的哈希值不同。比较t处的哈希值尝试删除的时间没有帮助。如果您实际使用同一对象(通过指针)不仅仅是一个相等的对象,那么它的散列当然会等于它的散列。但是集合已经根据它添加时的散列将对象存储在一些内部数据结构中。如果散列发生了变化,那么集合将找不到它,因为它是通过它的当前散列来查找的。我没有实现这两个方法,因为我检查了散列值,它存在于NSSet中,如果我遍历该集合,isEqual将返回YES。