双等号、-isEqual:和-hash

270 阅读2分钟

本体性和相等性

本体性: 是绝对的,物理意义上的,是判断物体是否是同一个本体。

相等性:是相对的,多数时候是人们根据需要定义的。

例如,有2枚一元的硬币,从本体性上来说,这2枚硬币是不同的,不相等的。但是从实际意义上来说,人们定义他们是相同的。

双等号 vs -isEqual:

双等号:本体性判断,指针是否相同,是否指向同一个内存地址。

-isEqual:通常是用来判断人们定义的相等性。


NSObject中的-isEqual:方法的默认实现是使用的 == 

例如,我们定义只要两个对象中的所有属性相等,我们就认为这两个对象是相等的。这时候我们就要重写-isEqual:方法,在里面判断两个对象中的所有属性是否相等,如果是就返回YES,不是就返回NO。这样,对比的结果就不是局限于本体性了。

在Foundation中继承NSObject的一些类中,有时候人们想要相等性的判断,而不是本体性的判断,所以Foundation中的一些类中默认实现了相等性的判断,例如

  • NSAttributedString -isEqualToAttributedString:
  • NSData -isEqualToData:
  • NSDate -isEqualToDate:
  • NSDictionary -isEqualToDictionary:
  • NSHashTable -isEqualToHashTable:
  • NSIndexSet -isEqualToIndexSet:
  • NSNumber -isEqualToNumber:
  • NSOrderedSet -isEqualToOrderedSet:
  • NSSet -isEqualToSet:
  • NSString -isEqualToString:
  • NSTimeZone -isEqualToTimeZone:
  • NSValue -isEqualToValue:


-hash方法

聊到-isEqual:方法的时候,通常-hash方法也会被牵扯进来。其实-hash方法不影响-isEqual的判等。

-hash方法返回的是NSUInteger类型,是根据对象运算得到的一个数,当对象被加入到NSMutableSet的时候,会调用-hash方法,用于通过映射计算对象在NSMutableSet的位置。如果hash结果能使得对象在NSMutableSet中的分布尽可能均匀,那么NSMutableSet的查找时间复杂对可以认为是O(1)。如果所有的对象的-hash方法返回同一个数,那么所有的对象在散列表中全部冲突,不管是拉链还是寻址,时间复杂度都会退化成数组的O(n)。