相关疑难解决方法(0)

覆盖isEqual:和hash的最佳实践

你如何isEqual:在Objective-C中正确覆盖?"catch"似乎是如果两个对象相等(由isEqual:方法确定),它们必须具有相同的散列值.

" 可可基础指南"的 " 内省"部分确实有一个示例,说明如何为名为的类重写,如下所示:isEqual:MyWidget

- (BOOL)isEqual:(id)other {
    if (other == self)
        return YES;
    if (!other || ![other isKindOfClass:[self class]])
        return NO;
    return [self isEqualToWidget:other];
}

- (BOOL)isEqualToWidget:(MyWidget *)aWidget {
    if (self == aWidget)
        return YES;
    if (![(id)[self name] isEqual:[aWidget name]])
        return NO;
    if (![[self data] isEqualToData:[aWidget data]])
        return NO;
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

它检查指针相等性,然后检查类相等性,最后比较使用的对象isEqualToWidget:,它只检查namedata属性.该示例显示的是如何覆盖hash.

比方说,让我们假设有其他属性不会影响平等age.如果没有hash方法被覆盖,使得只有namedata影响哈希?如果是这样,你会怎么做?只需添加的哈希 …

equality objective-c

266
推荐指数
11
解决办法
9万
查看次数

实现-hash/-isEqual:/ - isEqualTo ...:用于Objective-C集合

注意:以下SO问题是相关的,但它们和链接资源似乎都没有完全回答我的问题,特别是在实现对象集合的相等性测试方面.


背景

NSObject提供默认实现-hash(返回实例的地址,如(NSUInteger)self)和-isEqual:(NO除非接收者的地址和参数相同,否则返回).这些方法旨在根据需要进行覆盖,但文档清楚地表明您应该同时提供这两种方法,或者两者都不提供.此外,如果-isEqual:返回YES两个对象,那么-hash这些对象的结果必须相同.如果不是这样,当应该相同的对象(例如两个-compare:返回的字符串实例)NSOrderedSame被添加到Cocoa集合或直接比较时,就会出现问题.

上下文

我开发了CHDataStructures.framework,这是一个Objective-C数据结构的开源库.我已经实现了许多集合,目前正在改进和增强其功能.我想要添加的功能之一是能够将集合与另一个集合进行比较.

这些比较不应仅比较内存地址,而应考虑两个集合中存在的对象(包括排序,如果适用).这种方法在Cocoa中具有相当先例,并且通常使用单独的方法,包括以下方法:

我想使我的自定义集合对于相等性测试具有鲁棒性,因此可以安全地(并且可预测地)将它们添加到其他集合中,并允许其他集合(如NSSet)确定两个集合是否相等/等同/重复.

问题

一个-isEqualTo...:方法本身很有用,但是定义这些方法的类通常也会覆盖-isEqual:调用,[self isEqualTo...:]如果参数与接收者属于同一个类(或者可能是子类),或者[super isEqual:]不是.这意味着类还必须定义-hash,以便为具有相同内容的不同实例返回相同的值.

此外,Apple的文档-hash规定如下:(强调我的)

"如果一个可变对象被添加到使用的散列值,以确定该对象的集合中的位置的集合,由对象的哈希方法返回的值不能而所述对象是所述集合中的变化.因此,任一散列法不能依赖于对象的任何内部状态信息,或者必须确保对象在集合中时对象的内部状态信息不会发生变化.因此,例如,可变字典可以放在哈希表中但是你必须当它在那里时不要改变它.(注意,很难知道给定对象是否在集合中.)"

编辑: 我明白为什么这是必要的并完全同意推理 - 我在这里提到它提供额外的背景,并为了简洁而避开了为什么会这样的主题.

我的所有集合都是可变的,并且散列必须至少考虑一些内容,因此这里唯一的选择是将其视为编程错误来改变存储在另一个集合中的集合.(我的集合都采用NSCopying …

cocoa equality objective-c chdatastructures data-structures

47
推荐指数
1
解决办法
2万
查看次数

在可变Cocoa对象上实现-hash的技术

-hash当一个可变对象存储在一个集合中时,它的文档说不能改变,类似地-isEqual:说,-hash对于相同的对象,值的文档必须相同.

鉴于此,是否有人对最佳实施方式有任何建议-hash,使其满足这两个条件但实际上是智能计算的(即不仅仅是返回0)?有谁知道框架提供的类的可变版本如何做到这一点?

最简单的事情当然是忘记第一个条件(关于它不会改变),并确保我不会在一个集合中偶然改变一个对象,但我想知道是否有任何更灵活的解决方案.

编辑:我想知道在我改变对象的内部状态时是否可以维护2个契约(其中相等的对象具有相等的哈希值,并且当对象在集合中时哈希值不会改变).我倾向于说"不",除非我做了一些愚蠢的事情,总是为哈希返回0,但这就是我问这个问题的原因.

hash cocoa cocoa-touch objective-c

12
推荐指数
1
解决办法
2226
查看次数