I have an NSMutableOrderedSet that I'm adding and removing MTLModels from. The hash and isEqual methods will both return true for two objects, but containsObject will return false.
Sometimes this code works and sometimes it doesn't.
models count: 1
isEqual: 1
hashes equal: 1
containsObject: 0
How is it possible the below code could print out the above?
@property (nonatomic, strong) NSMutableOrderedSet *models;
- (void)remove:(MTLModel *)model {
NSLog(@"models count: %d", self.models.count);
MTLModel *modelInSet = (MTLModel *)self.models.firstObject;
NSLog(@"isEqual: %d", [modelInSet isEqual:model]);
NSLog(@"hashes equal: %d", modelInSet.hash == model.hash);
NSLog(@"containsObject: %d", [self.models containsObject:model]);
}
Update:
As a follow-up, this returns YES when the NSMutableOrderedSet returns NO:
[[self.models array] containsObject:model]
Update 2:
If I check if modelInSet is contained in self.models, that also returns NO, even though it's the object returned by firstObject.
You are probably mutating the object after adding it to the set. This is not allowed. The set does not recalculate hashes, so if you mutate the object, it will have a different hash from the one stored by the set. This is why creating a new collection (array in your case) works, i.e. because it recalculates all the hashes.
EDIT: To be clear, you can mutate an object after adding it to the set, but its hash value must not change.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With