2012-02-28 55 views
5

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

我的问题是来自白名单(只有白名单)的卡片可能在该集合中被复制。随机添加的卡片从不复制,并且计数总是正确的(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]]]; 
} 

我推翻了我的cardisEqual方法基于另一个回答过的问题在这里:

- (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副本)。

回答

15

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

其实,你总是需要确定这两个方法一起工作。从Apple's documentation

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

像这样的东西应该工作:

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

这样,你的哈希值取决于你使用,使比较相同的信息。

散列被数据结构如NSMutableSet用来快速将对象分组到不同的桶中。重要的是,如果两个对象相等,则它们具有相同的散列值。 (但是,如果两个对象具有相同的散列但不相等,那么您可以始终返回相同的数字,但这样您的性能将与使用数组相同。)数据结构

+0

啊完美,非常感谢。我正在把自己引向错误的道路,因为它有时似乎在工作,而不是其他人。 – hokiewalrus 2012-02-28 19:44:16