我有一个名为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]]];
}基于这里回答的另一个问题,我覆盖了card类的isEqual方法:
- (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个副本)。
发布于 2012-02-29 03:26:44
除了isEqual之外,您还需要覆盖hash。
事实上,您始终需要确保这两种方法协同工作。来自Apple's documentation
如果两个对象相等(由isEqual:方法确定),则它们必须具有相同的散列值。如果您在一个子类中定义了hash,并打算将该子类的实例放入一个集合中,那么最后一点尤其重要。
像这样的东西应该是有效的:
- (NSUInteger)hash {
return [[self cardName] hash];
}这样,您的散列依赖于您用来进行比较的相同信息。
像NSMutableSet这样的数据结构使用散列将对象快速分组到不同的存储桶中。重要的是,如果两个对象相等,则它们具有相同的散列值。(但是,如果两个对象具有相同的散列但不相等,这是可以的。因此,您可以始终从hash返回相同的数字,但这样您的性能将与使用数组相同。数据结构!)
https://stackoverflow.com/questions/9488211
复制相似问题