这个约定是因为当被存储在集合(如 NSDictionaryNSSet 在底层使用 hash 表数据的数据结构)的时候,如何查找这些对象。

    你总是应该用 isEqualTo<#class-name-without-prefix#>: 这样的格式实现一个相等性检查方法。如果你这样做,会优先调用这个方法来避免上面的类型检查。

    1. - (BOOL)isEqual:(id)object {
    2. if (self == object) {
    3. return YES;
    4. if (![object isKindOfClass:[ZOCPerson class]]) {
    5. return NO;
    6. return [self isEqualToPerson:(ZOCPerson *)object];
    7. }
    8. - (BOOL)isEqualToPerson:(Person *)person {
    9. if (!person) {
    10. return NO;
    11. BOOL namesMatch = (!self.name && !person.name) ||
    12. [self.name isEqualToString:person.name];
    13. BOOL birthdaysMatch = (!self.birthday && !person.birthday) ||
    14. [self.birthday isEqualToDate:person.birthday];
    15. return haveEqualNames && haveEqualBirthdays;

    一个对象实例的 hash 计算结果应该是确定的。当它被加入到一个容器对象(比如 NSArray, NSSet, 或者 )的时候这是很重要的,否则行为会无法预测(所有的容器对象使用对象的 hash 来查找或者实施特别的行为,如确定唯一性)这也就是说,应该用不可变的属性来计算 hash 值,或者,最好保证对象是不可变的。