• 重载hash与isEqual:方法


    重载hash与isEqual:方法

    前言

    NSObject 自带了hash与isEqual:方法,服务于具有hash表结构的数据结构。NSObject自带的hash函数相当于hash表中的f(key)函数中的key,这“唯一”的key需要用户自己产生,至于用什么算法由用户自己决定。

    准备

    //
    //  Model.h
    //  Hash
    //
    //  Created by YouXianMing on 16/4/15.
    //  Copyright © 2016年 YouXianMing. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface Model : NSObject <NSCopying>
    
    @property (nonatomic, strong) NSString  *firstName;
    @property (nonatomic, strong) NSString  *lastName;
    
    @end
    //
    //  Model.m
    //  Hash
    //
    //  Created by YouXianMing on 16/4/15.
    //  Copyright © 2016年 YouXianMing. All rights reserved.
    //
    
    #import "Model.h"
    
    #define NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger))
    #define NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (NSUINT_BIT - howmuch)))
    
    @implementation Model
    
    - (id)copyWithZone:(nullable NSZone *)zone {
    
        Model *result = [[[self class] allocWithZone:zone] init];
        
        result.firstName = self.firstName;
        result.lastName  = self.lastName;
        
        return result;
    }
    
    - (NSUInteger)hash {
    
        return NSUINTROTATE([_firstName hash], NSUINT_BIT / 2) ^ [_lastName hash];
    }
    
    - (BOOL)isEqual:(id)object {
    
        if (self == object) {
            
            return YES;
        }
        
        if ([object isKindOfClass:[Model class]]) {
            
            return [self hash] == [object hash];
            
        } else {
        
            return NO;
        }
    }
    
    @end

    测试

    1. 测试对象是否相同(注意打印信息)

    之所以会相同是因为两个对象的hash算法以属性值的唯一性来确保对象的差异性,也就是说,只要两个对象属性值一致,那这两个对象的就是相等的。

    2. 测试字典setObject:forKey:方法(注意打印信息)

    字典通过modelB对象作key值竟然找到了modelA作为key值时存储的值,这是因为我们已经让modelA与modelB“相等了”,可以参考测试1。

    字典在设置key值的时候是需要复制这个key值对象的(这个key值对象需要实现NSCopying协议),也就是说,我们的modelA在作为key值的时候已经被字典复制一份了,因为字典需要确保这个key值不可变,否则,做为key值的对象通过修改内部属性而导致了这个对象的hash值发生变化,会出现找不到对象的情况。

    大家可以观察一下断点流程(字典先获取外部对象的hash值,然后与自己的key值对象进行比较执行isEqual:方法,如果认为比较结果一致,就确保是同一个对象)

    字典在执行setObject:forKey:方法的时候,会先执行这个key值对象的hash方法用以生成一个键值,然后再copy这个key值对象。

    3. 测试NSSet的addObject:方法(注意打印信息)

    addObject:方法执行的流程如下:先获取对象modelA的hash值,再添加modelB的时候获取modelB的hash值,然后进行比较,如果两者的比较结果一致,则认为这是相同的对象。

  • 相关阅读:
    计算机视觉的常用测试数据集和源码
    Demo:基于 Flink SQL 构建流式应用
    102万行代码,1270 个问题,Flink 新版发布了什么?
    bilibili 实时平台的架构与实践
    阿里云2020上云采购季来啦!降本增效1亿补贴!
    阿里云助力宁波市教育局“甬上云校”停课不停学
    Quick BI新版本功能解读系列之-V3.5
    百万TPS高吞吐、秒级低延迟,阿里​搜索离线平台如何实现?
    五分钟学会使用 go modules(含在家办公使用技巧)
    OAM 深入解读:OAM 为云原生应用带来哪些价值?
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/5397798.html
Copyright © 2020-2023  润新知