美文网首页
OCLint规则:If you override isEqual

OCLint规则:If you override isEqual

作者: Pandakingli | 来源:发表于2018-03-01 15:40 被阅读0次

    一、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

    相关文章

      网友评论

          本文标题:OCLint规则:If you override isEqual

          本文链接:https://www.haomeiwen.com/subject/mbvgxftx.html