Why doesn't NSMutableSet remove an object contained in it?

738 Views Asked by At

I have an NSMutableSet set that contains custom made objects who are a subclass of SKNode. I am making a game where these objects are added and removed from the NSMutableSet. I am adding and removing from the main thread, so threading isn't an issue. For some reason sometimes an object isn't removed because it can't be found. The following method returns NO:

[self.set containsObject:object]

I looked into the this problem and printed the address and hash number of the object and all the objects in the NSMutableSet, and sure enough it appears in the set.

What could be the reason that the object isn't found if the address and hash numbers equal? I understand that the containsObject method uses the isEqual which compares these two values.

2

There are 2 best solutions below

7
Rob Napier On BEST ANSWER

The result of hash must be equal and the result of isEqual: must be YES. Just matching the hash is not sufficient. Have you checked isEqual:? The default isEqual: compares object identity, not hash. hash is allowed to be used by collections to speed up comparisons, but it is only an optimization. If two objects return YES for isEqual: they must also return the same hash, but the converse is not true.

1
gnasher729 On

To use objects as elements of NSSet, keys of NSDictionary etc. they need to implement the hash method and the isEqual: method. If you don't have your own implementation, hash returns the object pointer and isEqual compares object pointers and everything will work just fine.

If you implemented hash and isEqual: yourself, you must make sure of two things: 1. The hash value and the result of isEqual most not change while the object is in the set (changing an NSMutableString that is stored in an NSSet would be a very bad idea). 2. hash and isEqual: must be consistent: Two objects that compare equal must return the same hash value.