OCLint规则:If you override isEqual you must override hash too --了解isEqual与hash

一、isEqual的作用

isEqual的作用:判断两个对象是否相等

对于基本类型, ==运算符比较的是值;
对于对象类型, ==运算符比较的是对象的地址(即是否为同一对象)

Objective-C和Java不支持运算符重载, C++支持运算符重载,这样的话可以在运算符重载的时候做判断

二、重写isEqual方法

Cocoa Framework中定义的类型,
NSString isEqualToString
NSDate isEqualToDate
NSArray isEqualToArray
NSDictionary isEqualToDictionary
NSSet isEqualToSet
isEqual方法已经实现好了。
对于自定义类型来说, 通常需要重写isEqual方法
首先定义TestModel类如下

@interface TestModel : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *color;

@end
- (BOOL)isEqual:(id)object {

  if (self == object) {
        return YES;
    }

    if (![object isKindOfClass:[TestModel class]]) {
        return NO;
    }

    return [self isEqualToTestModel:(TestModel *)object];
}

- (BOOL)isEqualToTestModel:(TestModel *)tModel {

   if (!tModel) {
        return NO;
    }

    BOOL equalName = (!self.name && !tModel.name) || [self.name isEqualToString:tModel.name];

    BOOL equalColor = (!self.color && !tModel.color) || [self.birthday isEqualToString:tModel.color];

    return equalName && equalColor;

}

主要步骤:
1: ==运算符判断是否是同一对象, 同一对象必然完全相同

2: 判断是否是同一类型, 可以提高判等的效率, 还可以避免隐式类型转换带来的潜在风险

3: 通过封装的isEqualToTestModel方法, 提高代码复用性

4: 判断TestModel是否是nil, 做参数有效性检查

5: 对各个属性分别使用默认判等方法进行判断

6: 返回所有属性判等的与结果

三、重写hash方法

hash方法只在对象被添加至NSSet和设置为NSDictionary的key时会调用
NSSet添加新成员时, 需要根据hash值来快速查找成员, 以保证集合中是否已经存在该成员
NSDictionary在查找key时, 也利用了key的hash值来提高查找的效率

hash方法主要是用于在Hash Table查询成员用的。
为了优化判等的效率, 基于hash的NSSet和NSDictionary在判断成员是否相等时, 会这样做

第一步: 集合成员的hash值是否和目标hash值相等, 如果相同进入第二步判断, 如果不等, 直接判断不相等
第二步: hash值相同(第一步)的情况下, 再进行对象判等, 作为判等的结果

hash值是对象判等的必要非充分条件

- (NSUInteger)hash {
    return [super hash];
}
//这样重写hash方法,是有隐患的。
//[super hash]返回的就是该对象的内存地址
//如果两个对象地址不同,但是内容完全一样,此时就都能加入NSSet了

Mattt ThompsonEquality中给出的结论就是

In reality, a simple XOR over the hash values of critical properties is sufficient 99% of the time(对关键属性的hash值进行位或运算作为hash值)

对于TestModel

- (NSUInteger)hash {
    return [self.name hash] ^ [self.color hash];
}

参考文章:
Mattt Thompson
Equality
NSObject的hash方法
浅拷贝深拷贝以及 Hash/Equal

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值