当我们使用MutableSet添加对象,保持对象唯一,实现-(NSUInteger)hash
和-(BOOL)isEqual:(id)object
方法时,我不知道何时会调用这两个方法?
答案 0 :(得分:1)
我不确定,我是否正确理解你的Q.但是,......
一个。你不应该关心时间,方法被称为。做什么的?对象是否等于另一个对象不依赖于时间,它会被测试。 (除非同时改变了对象。)
B中。唯一性不需要-hash
差异。 不同的对象可能具有相同的哈希值。你很快就会看到,这很平常。
℃。这是一个城市传说NSSet
或NSMutableSet
保证唯一性。插入对象时,两者都检查唯一性。但它不会(也不能)检查插入的对象是否会更改其值,使其在插入后变为等于另一个。
NSMutableString *amin = [@"Amin Negm-Awad" mutableCopy];
NSMutableString *firstname = [@"Amin" mutableCopy];
NSSet *set = [NSSet setWithObjects:amin, firstname];
[firstname appendString:@" Negm-Awad"];
显然两个字符串都在集合中,两个字符串都相等。
如果集合的成员(不是集合本身)是不可变的,则只能保证唯一性。
d。啊,成员的不变性:当对象的哈希值是集合的成员时,不允许更改该对象的哈希值。除了事实之外,无法检测到对象是否是集合的成员,集合-hash
之外没有什么意义。
这意味着对于可变对象,您无法依赖于对象的属性来实现-hash
:由于可变对象的属性可以更改,这将更改哈希值。
此外,由于对象的哈希值对于相等的对象是相等的,因此不能将初始化时的哈希值设置为或多或少的随机数。你无法知道,如果对象变得与另一个对象相等,但在这种情况下你必须保证哈希公平。
简化日志:
如果该组成员是可变的,请不要关心很好的哈希算法。只需返回一个哈希值,该哈希值对于该类的所有实例对象都是常量。这很糟糕,但其他所有解决方案都会中断。
在-isEqual:
中,只需比较对象的属性即可。它不应该取决于时间,测试运行。
答案 1 :(得分:1)
你的问题不明确,所以这是一个猜测:
在你写的评论中写道:
如果我创建了类MONInteger,添加到NSMutableSet,创建两次simlar实例,如果我登录,则有两个对象
如果您定义了要插入集合的类,或者执行需要相等的任何其他操作,则需要在类中定义hash
和isEqual
方法,例如:< / p>
@implementation MONInteger
- (NSUInteger) hash
{
// ...
}
- (BOOL) isEqual:(id)object
{
// ...
}
// other methods of the class
@end
这两种方法必须实现的基本逻辑是:
isEqual
如果(且仅当)参数YES
是object
的实例和当前对象(MONClass
),则应返回self
和object
代表相同的MONClass
值(不是同一个MONClass
对象)。hash
必须为isEqual
返回YES
的对象返回相同的值。 可能为不相等的对象返回相同的值,但如果它返回的不同值的数量很大并且传播得很好则更好。 (如果不清楚则查找哈希算法。)当一个对象被添加到一个集合时,将在被插入的对象和已经在集合中的对象上调用上述方法。然而,这不是一个重要的观点,它们在需要时被调用,它们的编写方式并不取决于它们何时被调用。我怀疑你的语言在这里有误导,你不打算问这个(这里不是负面的,我的普通话/广东话,我希望你的第一语言,不存在!)
如果您的集合中有两个不同的MONInteger
对象代表相同的值,那么您还没有实现hash
和isEqual
,或者您已经错误地实现了它们,所以这样做了没有提供正确的平等检查。
HTH