美文网首页
《Effective Objective-C 2.0》- 7:理

《Effective Objective-C 2.0》- 7:理

作者: WhistleCai | 来源:发表于2018-06-11 16:34 被阅读0次

一、同等性判断
1.“==”

(1)对于对象类型,“==” 比较的是对象的地址,即是否为同一个对象

NSString *str = @"test1";
NSString *strCopy = [str copy];
NSString *strNew = [NSString stringWithFormat:@"test%@", @1];

BOOL equalA = (str == strCopy); // YES
BOOL equalB = (str == strNew);  // NO

(2)对于基本类型,“==”比较的是值

NSInteger x = 123;
NSInteger y = 123;
NSInteger z = 1234;

BOOL equal0 = (x == y); // YES
BOOL equal1 = (x == z);  // NO

2.isEqual

(1) isEqual:NSObject 协议中声明的方法来判断两个对象的等同性,可直接使用

NSString *str = @"test1";
NSString *strNew = [NSString stringWithFormat:@"test%@", @1];

BOOL equalD = [str isEqual:strNew]; // YES 

(2)iOS系统已经实现了部分NSObject子类的isEqual方法,可直接使用

NSString - isEqualToString
NSArray - isEqualToArray
NSDictionary - isEqualToDictionary
NSSet - isEqualToSet

(3)对于自定义的类型来说,需要重写isEqual方法:

//重写系统的isEqual
- (BOOL)isEqual:(id)object {
    //Step 1: ==运算符判断是否是同一对象, 因为同一对象必然完全相同
    if (self == object) {
        return YES;
    }
    //Step 2: 判断是否是同一类型, 这样不仅可以提高判断的效率, 还可以避免隐式类型转换带来的潜在风险
    if (![object isKindOfClass:[Person class]]) {
        return NO;
    }
    //Step 3: 通过封装的isEqualToPerson方法, 提高代码复用性
    return [self isEqualToPerson:(Person *)object];
}

//自定义方法来执行有意义的值比较
- (BOOL)isEqualToPerson:(Person *)person {
    //Step 4: 判断person是否是nil, 做参数有效性检查
    if (!person) {
        return NO;
    }
    //Step 5: 对各个属性分别使用默认判等方法进行判断
    BOOL haveEqualNames = (!self.name && !person.name) || [self.name isEqualToString:person.name];
    BOOL haveEqualBirthdays = (!self.birthday && !person.birthday) || [self.birthday isEqualToDate:person.birthday];
    //Step 6: 返回所有属性判等的与结果
    return haveEqualNames && haveEqualBirthdays;
}

(4)isEqual和hash的联系:如果 isEqual: 方法判断两个对象相等,那么其 hash 方法必须返回同一个值

3.hash

(1)哈希表:hash表是一种特殊的数据结构,能够快速定位到想要查找的记录

在数组中查找某个成员

  1. 遍历数组中的成员
  2. 将取出的值与目标值比较, 如果相等, 则返回该成员

使用hash

  1. 通过hash值直接找到查找目标的位置
  2. 如果目标位置上有多个相同hash值得成员, 此时再按照数组方式进行查找

结论:若是无多个相同hash值的成员,使用hash查找较快

(2)hash方法什么时候被调用:

//对象被添加至NSSet
[set1 addObject:person1];
// 设置为NSDictionary的key
[dictionaryValue2 setObject:person2 forKey:kKey2];

(3)hash方法与isEqual的关系:hash值是对象判断的必要非充分条件

1.先判断hash是否相等,如果不相等则直接判定,如果相等,则进入第二步
2.重写isEqual方法

(4)在项目中的具体使用:重写hash方法

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

    // NSObject的hash值是调用hash方法的对象地址,一般不用,需要重写一个hash的方法实现
    //return [super hash]; 
}

二、 深度同等行判断

比较两个数组是否相等的话可以使用深度同等性判断方法:

1.先比较数组的个数
2.再比较两个数组对应位置上的对象均相等。

要点:

  • 若想检测对象的等同性,请提供“ isEqual:” 与 hash 方法。
  • 相同的对象必须具有相同的哈希码,但是两个哈希码相同的对象却未必相同。
  • 不要盲目地逐个检测每条属性,而是应该依照具体需求来制定检测方案。
  • 编写hash方法时,应该使用计算速度快而且哈希码碰撞几率低的算法。

相关文章

网友评论

      本文标题:《Effective Objective-C 2.0》- 7:理

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