iOS 中对象等同性 isEqual:和 hash
对象等同性
对象的等同性 :我们在使用对象的时候,往往需要判断两个对象是否相等,这种相等包含两种含义:
在程序上是否是同一块内存地址
在语义上,是否能指代同一对象
由此可见
==:比较的是两个指针本身,而不是其所指的对象
isEqual:判断两个对象是否相等
判断等同性的方法
-(BOOL)isEqual:(id)object;
这个方法是用来判断两个对象是否相等的。hash
是用在哈希表表结构的表地址。
由官方文档可知,
isEqual:
方法返回YES
,那么hash
必然相等如果
hash
相等,那么isEqual:
返回的不一定是YES
首先我们定义一个 Person 类,其中包含 name 和 age 俩个属性,当 person 的 name 和 age 同时一致时,我们认为这俩个对象是同一个人
-(BOOL)isEqual:(id)object;
1、判断俩个对象的指针是否相同
2、判断俩个对象所属类是否相同
3、判断每个属性是否相同
- (NSUInteger)hash
为什么要 hash 方法?
比如我们要从数组中查找某个成员
step1:遍历数组中成员
step2:将取出的值与目标值比较,如果相等,则返回该成员
这样查找比较复杂,为了提高查找速度,Hash Table 出现了,当成员被加入到 Hash Table 中时,会给它分配一个
hash
值,以标识该成员在集合中的位置,分配这个 hash 值(即用于查找集合、数组中成员的位置标识)就是通过 hash 算法计算出来的,且 hash 方法返回的 hash 值最好唯一,和数组相比,基于hash
值索引的 hash Table 查找某个成员的过程就是step1:通过 hash 值直接找到查找目标的位置
step2:如果目标位置上有多个相同
hash
值成员,此时再按照数组方式查找hash 方法什么时候被调用?
log:
hash
值的目的是尽最大可能返回一个标识,但并不是一定要是唯一的。根据 Person 的设定,能标识 Person 的是 name 和 age 属性,所以我们可以根据这两个属性来进行hash
值的生成。
保证
hash
的不可变在容器中使用对象时,要尽量避免对象
hash
值的不可变,或者说在将对象放入容器后不再改变对象的内容,这样才能避免容器中出现错误的数据
自定义类的等同性判断
在编写判定方法时,需要重写“isEqual”方法,如果对比参数与实际类属于同一类(类似 isEqualToString:),那么就调用自己的判定方法,否则就交给父类判断例如 Person 类
等同性判断的执行深度
创建等同性判断方法时, 需要决定是根据整个对象来判断等同性还是仅根据几个字段来判断
NSArray
检测方式是先看俩个数组所含对象个数是否相同,如果相同,那么每个位置的俩个对象身上调用isEqual
方法,如果对应位置相等,那么俩个数组就相等,这种方式叫深度等同性判断如果我们的 Person 类的实例是根据数据库的数据创建的,那么其中会有一个属性被定义为主键,这种情况下我只需要根据主键标识来判断即可
是否需要在等同性判断方法中检测全部字段取决于受测对象,只有类的编写者才可以确定俩个对象实例在何种情况下应判定为相等
版权声明: 本文为 InfoQ 作者【NewBoy】的原创文章。
原文链接:【http://xie.infoq.cn/article/d41e5ed88e98c4ebf64b41fe4】。文章转载请联系作者。
评论