6

我有一个名为的自定义类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 个副本)。

4

1 回答 1

17

您需要覆盖hashisEqual.

事实上,您总是需要确保这两种方法一起工作。来自苹果的文档

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

像这样的东西应该工作:

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

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

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

于 2012-02-28T19:26:44.483 回答