Files
knowledge-kit/Chapter1 - iOS/1.37.md
2020-02-25 17:46:51 +08:00

35 lines
2.7 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数组、集合、字典与 hash、isEqual 方法的关联
1. NSArray 允许重复添加元素添加元素的时候不查重所以不会调用上面2个方法。在移出元素的时候会依次遍历数组内的元素每个元素调用 **isEqual** 方法remove 方法传入的元素作为参数),所有返回真值的元素都会被移除。在字典中不涉及 hash 方法。
2. NSSet 不允许重复添加元素,所以在添加新元素的时候,该元素的 **hash** 方法会被调用,若集合中不存在与此元素 hash 相同的元素,则它会被直接加入集合,不调用 **isEqual** 方法;若存在,则依次调用该集合每个元素的 **isEqual** 方法,返回真值则判等,不加入,处理结合,若返回 false 则判定集合内不存在该元素,将其加入。
3. 集合中移除元素时,首先调用它的 **hash方法**,若集合中存在与其 **hash值** 相等的元素,则调用该元素的 **isEqual方法**,若返回真值则判断,进行移除;若不存在,则会依次调用集合中每个元素的 **isEqual方法**,只要找到一个返回真值的元素,就进行移除,并结束整个过程(所有这样会有其它满足 isEqual 方法但却漏掉未被删除的元素)。调用 contains 方法时类似
4. 因此如果自定义对象被加入到集合或作为字典的 key 时,需要同时重写 isEqual 方法和 hash 方法,这样,若集合存在某元素,则调用它的 contains 和 remove 方法时,可以在 O(1) 完成查询,否则需要 O(n) 完成。
 
5. 需要注意的是NSDictionary 的 key、value 都说对象类型即可,但是被设为 key 的对象需要遵循 NSCopying 协议。
6. hash 方法出现的目的是:当我们从数组中查找元素时,需要依次遍历数组中的元素,时间复杂度为 O(n),为了解决效率问题,引入了 Hash Table 方法。当添加元素的时候,为每个元素设置了 hash 值,这样当下次查找的时候就直接通过 hash 值找到对应的位置,时间复杂度为 O(1)。设计一个合理的 hash 算法的指标是对于每个参数,其返回的 hash 值唯一。
7. 查阅资料可知,一个推荐的自定义对象的 **hash** 算法是将关键属性的 hash 值,按照位或运算
```
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSDate *birthday;
@end
- (NSUInteger)hash{
return [self.name hash] ^ [self.birthday hash];
}
```
8. NSObject 类中的 equal 方法的判断是包括内存地址的也就是说NSObject 若想判断2个对象相等那么这2个对象的内存地址必须相等