Tag: chdatastructures

为Objective-C集合实现-hash / -isEqual:/ -isEqualTo …:

注意:下面的SO问题是相关的,但是他们和链接的资源似乎都不能完全回答我的问题,特别是在实现对象集合的平等testing方面。 覆盖-isEqual和-hash的最佳实践 在可变的cocoa对象上实现-hash的技巧 背景 NSObject提供了默认的实现-hash (它返回实例的地址,比如(NSUInteger)self )和-isEqual:除非接收者的地址和参数相同,否则返回NO 。 这些方法被devise为根据需要被覆盖,但是文档清楚地表明你应该提供或者不提供。 此外,如果-isEqual:对于两个对象返回YES ,则这些对象的-hash结果必须相同。 如果不是这样,那么当对象应该是相同的,比如两个string实例(其中的NSOrderedSame -compare: returns NSOrderedSame )被添加到Cocoa集合中,或者直接进行比较时,问题会随之而来。 上下文 我开发了CHDataStructures.framework ,一个Objective-C数据结构的开源库。 我已经实现了一些集合,并且正在改进和增强它们的function。 我想要添加的function之一是能够比较集合的平等与另一个。 这些比较应该考虑两个集合中存在的对象(包括sorting,如果适用),而不是只比较内存地址。 这种方法在cocoa中有相当的先例,并且通常使用一种单独的方法,包括以下方法: -[NSArray isEqualToArray:] -[NSDate isEqualToDate:] -[NSDictionary isEqualToDictionary:] -[NSNumber isEqualToNumber:] -[NSSet isEqualToSet:] -[NSString isEqualToString:] -[NSValue isEqualToValue:] 我想使自定义集合对于相等性testing的健壮性,所以他们可以安全地(可预测地)将其添加到其他集合中,并允许其他集合(如NSSet)确定两个集合是否相等/等同/重复。 问题 一个-isEqualTo…:方法可以很好地工作,但是定义这些方法的类通常也会覆盖-isEqual:如果参数是相同的类(或者可能是子类),则调用[self isEqualTo…:]接收者,否则[super isEqual:] 。 这意味着该类还必须定义-hash ,以便为具有相同内容的不同实例返回相同的值。 另外,苹果的-hash文件规定如下:(强调我的) “如果将可变对象添加到使用散列值确定对象在集合中的位置的集合中,则在对象位于集合中时,由对象的散列方法返回的值不得更改,因此无论是散列方法不能依赖任何对象的内部状态信息, 或者当对象位于集合中时,必须确保对象的内部状态信息不发生变化。因此,例如,可以将可变字典放在哈希表中,但必须而不是在它那里改变它(注意可能很难知道一个给定的对象是否在一个集合中)。“ 编辑: 我当然明白为什么这是必要的,并完全同意推理 – 我在这里提到它提供了额外的背景,并且为了简洁起见跳过为什么是这样的话题。 我所有的集合都是可变的,哈希将不得不考虑至less一些内容,所以这里唯一的select是将其存储在另一个集合中的集合进行变异时,将其视为编程错误。 (我的集合都采用NSCopying ,所以像NSDictionary集合可以成功地作为一个副本作为一个键等) […]