重载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 / ) ^ [_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值,然后进行比较,如果两者的比较结果一致,则认为这是相同的对象。

重载hash与isEqual:方法的更多相关文章

  1. NSDictionary实现原理-ios哈希hash和isEqual

    NSDictionary实现原理-ios哈希hash和isEqual   OC中自定义类的NSCopying实现的注意事项(isEqual & hash实现) http://blog.csdn ...

  2. java中的方法重载与重写以及方法修饰符

    1. 方法重载Overloading , 是在一个类中,有多个方法,这些方法的名字相同,但是具有不同的参数列表,和返回值 重载的时候,方法名要一样,但是参数类型和参数个数不一样,返回值类型可以相同,也 ...

  3. c# 重载运算符(+-|&)和扩展方法

    通常我们需要对class的相加,相减,相乘 等重载以适应需求, 如caml查询的时候,我们可以定义一个caml类,然后来操作这些查询. 首先,我们定义一个class为Test public class ...

  4. HashMap解决hash冲突的方法

    HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置.当程序执行 map.put(String,Obect)方法 时,系统将调用String的 hashCode() 方法得到其 h ...

  5. Java重载重写与实现方法的规则

    这几天在实训过程中做到了一个题,这个题目问的是 非抽象类实现接口后,必须实现接口中的所有抽象方法,除了abstract外,方法头必须完全一致.这句话是错误的.然后在做错以后自己总结一下重载 重写 和实 ...

  6. java中重载变长参数方法

    一.测试代码 package com.demo; public class Interview { public static void test(int i){ System.out.println ...

  7. 解决Hash碰撞冲突方法总结

    Hash碰撞冲突 我们知道,对象Hash的前提是实现equals()和hashCode()两个方法,那么HashCode()的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰 ...

  8. 重载Cocos2D生存期的方法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交 ...

  9. C#方法重载(overload)方法重写(override)隐藏(new)

    一.重载:同一个作用域内发生(比如一个类里面),定义一系列同名方法,但是方法的参数列表不同.这样才能通过传递不同的参数来决定到底调用哪一个. 值得注意的是,方法重载只有通过参数不同来判断调用哪个方法, ...

随机推荐

  1. KnockoutJs学习笔记(十二)

    value binding一般适用于input.select.textarea等form elements中,能够将view model中的属性和相关联的DOM element的值(value)连接起 ...

  2. 如何在CI中写工具类,在哪个目录写

    在Libraries目录写工具类,可以参考项目中七牛的集成写法 而Helps目录写的是辅助函数(公共函数)这一类的

  3. [转] HTML 获取屏幕、浏览器、页面的高度宽度

    本篇主要介绍Web环境中屏幕.浏览器及页面的高度.宽度信息. 目录 1. 介绍:介绍页面的容器(屏幕.浏览器及页面).物理尺寸与分辨率.展示等内容. 2. 屏幕信息:介绍屏幕尺寸信息:如:屏幕.软件可 ...

  4. PowerDesigner的安装

    1.下载 2.步骤 3.效果 二:破解 1.参考文档 https://www.7down.com/soft/180716.html 2.说明 主要是一个文件,替换掉文件中的文件即可.

  5. ref:Spring JdbcTemplate+JdbcDaoSupport实例

    ref:https://www.yiibai.com/spring/spring-jdbctemplate-jdbcdaosupport-examples.html 在Spring JDBC开发中,可 ...

  6. object-c中NSString与int和float的相互转换

    1,字符串拼接 NSString *newString = [NSString stringWithFormat:@"%@%@",tempA,tempB]; 2,字符转int in ...

  7. hdu 5784 How Many Triangles 计算几何,平面有多少个锐角三角形

    How Many Triangles 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5784 Description Alice has n poin ...

  8. mysql分页查询优化(索引延迟关联)

    对于web后台报表导出是一种常见的功能点,实际对应服务后端即数据库的排序分页查询.如下示例为公司商户积分报表导出其中一个sql ,当大批量的导出请求进入时候,mysql的cpu急剧上升瞬间有拖垮库的风 ...

  9. ios网络请求

    1.AFNetworking object 2.Alamofire swift

  10. Docker系列之(五):使用Docker Compose编排容器

    1. 前言 Docker Compose 是 Docker 容器进行编排的工具,定义和运行多容器的应用,可以一条命令启动多个容器. 使用Compose 基本上分为三步: Dockerfile 定义应用 ...