NSMutableSet包含重复项

时间:2012-02-28 19:15:23

标签: objective-c xcode nsmutableset

我有一个名为card的自定义类,我需要从一组随机大小的卡片中创建一组10张独特的卡片。此外,我需要首先包括任何列入白名单的卡片,以确保它们始终包含在内。

我的问题是来自白名单的卡(并且只有白名单)可能在集合中重复。随机添加的卡永远不会重复,计数总是正确的(10)。我无法弄清楚为什么isEqual似乎有时会起作用,但并非总是如此。

这是我创建集合的地方(randoms是要从中挑选的潜在卡片数组):

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]]];
}

我根据此处回答的其他问题覆盖了isEqual课程的card方法:

- (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;
}

它似乎完美无缺,除非我添加白名单卡片时,我无法弄清楚我是如何以重复方式结束的(但从不超过2个副本)。

1 个答案:

答案 0 :(得分:16)

除了hash之外,您还需要覆盖isEqual

事实上,总是需要确保这两种方法协同工作。来自Apple's documentation

  

如果两个对象相等(由isEqual:方法确定),则它们必须具有相同的哈希值。如果在子类中定义哈希并打算将该子类的实例放入集合中,则最后一点尤为重要。

这样的事情应该有效:

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

这样,您的哈希值取决于您用于进行比较的相同信息。

哈希由NSMutableSet等数据结构用于快速将对象分组到不同的桶中。重要的是,如果两个对象相等,则它们具有相同的散列值。 (但是,如果两个对象具有相同的哈希但不相等,那就没关系。所以你总是可以从hash返回相同的数字,但是你的性能与使用数组相同。数据结构!)