有没有办法确定一个类是否适合作为键并且可以按预期工作,例如我想使用NSIndexPath作为NSDictionary中的键,但我不确定两个不同的NSIndexPath实例是否具有相同的整数values 将始终返回相同的哈希值。
3 回答
苹果的 NSObject 的 isEqual 文件说:
如果两个对象相等,则它们必须具有相同的哈希值。如果您在子类中定义 isEqual: 并打算将该子类的实例放入集合中,那么最后一点尤其重要。确保您还在子类中定义哈希。
看下面的代码:
NSIndexPath *indexPath1 = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *indexPath2 = [NSIndexPath indexPathForRow:0 inSection:0];
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
NSLog(@"NSIndexPath isEqual's Result: %d", [indexPath1 isEqual:indexPath2]);
NSLog(@"NSObject isEqual's Result: %d", [obj1 isEqual:obj2]);
输出结果:
NSIndexPath isEqual 的结果:1
NSObject isEqual 的结果:0
NSObject isEqual的实现 是comare两个对象的地址,hash实现是返回对象的地址。
NSIndexPath继承自NSObject,根据 NSIndexPath isEqual 输出结果,NSIndexPath 的 isEqual 实现应该覆盖超类的 isEqual 方法,NSIndexPath 也覆盖超类的 hash 方法。
另外,NSIndexPath 也符合 NSCopying 协议。
所以 NSIndexPath 可以作为 NSDictionary 的 Key 类。
对象如何作为键取决于它如何实现 isEqual:。这将确定两个键是否碰撞。
例如,当路径具有相同的索引集时,索引路径是相等的 - 因此会发生冲突。所以描述相同路径的两个不同对象将被字典视为相同的键......可能是您希望的样子。
NSDictionary 键有三个要求:
- 支持 NSCopying 协议
- 合理的-hash方法
- 是平等的
NSIndexPath 应该没问题。