NSMutableSet contains Duplicates

戏子无情 提交于 2019-12-12 10:52:36

问题


I have a custom class called card and I need to create a set of 10 unique cards from an array of cards of a random size. Also, I need include any whitelisted cards first to make sure they are always included.

My problem is cards from the whitelist (and only the whitelist) are potentially duplicated in the set. The cards randomly added are never duplicated, and the count is always correct (10). I can't figure out why isEqual seems to work sometimes but not always.

Here is where I create the set (randoms is the array of potential cards to be picked from):

NSMutableSet *randomCards = [NSMutableSet setWithCapacity:10];

[randomCards addObjectsFromArray:whiteListArray];

while ([randomCards count] < 10) {
    NSNumber *randomNumber = [NSNumber numberWithInt:(arc4random() % [randoms count])];
    [randomCards addObject:[randoms objectAtIndex:[randomNumber intValue]]];
}

I overrode the isEqual method for my card class based on another question answered here:

- (BOOL)isEqual:(id)other {

if (other == self)
    return YES;
if (!other || ![other isKindOfClass:[self class]])
    return NO;
return [self isEqualToCard:other];

}

- (BOOL)isEqualToCard:(Card *)myCard {

if (self == myCard) {
    return YES;
}
if ([self cardName] != [myCard cardName] && ![(id)[self cardName] isEqual:[myCard cardName]])
    return NO;

return YES;
}

It seems to work perfectly except when I add in the whitelist cards, I can't figure out how I'm ending up with duplicates (but never more than 2 copies).


回答1:


You need to override hash in addition to isEqual.

In fact, you always need to make sure these two methods work together. From Apple's documentation:

If two objects are equal (as determined by the isEqual: method), they must have the same hash value. This last point is particularly important if you define hash in a subclass and intend to put instances of that subclass into a collection.

Something like this should work:

- (NSUInteger)hash {
    return [[self cardName] hash];
}

This way your hash depends on the same information that you're using to make the comparison.

The hash is used by data structures like NSMutableSet to quickly group objects into different buckets. It's important that if two objects are equal, they have the same hash value. (It's OK, however, if two objects have the same hash but are not equal. So you could always return the same number from hash, but then your performance would be the same as using an array. Data structures!)



来源:https://stackoverflow.com/questions/9488211/nsmutableset-contains-duplicates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!