【iOS】—— isMemberOfClass isKindOfClass以及源码

【iOS】—— isMemberOfClass & isKindOfClass以及源码

    • isa指针
    • 示例
    • 源码解析:
      • isKindOfClass:源码解析(实例方法和类方法)
      • isMemberOfClass:源码解析(实例方法和类方法)
      • 源码分析总结:

isa指针

isa指针的指向: 对象的 isa 指向 类; 类的 isa 指向 元类;元类的 isa 指向 根元类;根元类的 isa 指向 自己。
类的superclass的指向: 类的 superclass 指向 父类, 父类的 superclass 指向 根类 ,根类的superclass 指向 nil。
元类的superclass的指向: 元类的 superclass 指向 父类的元类,父元类的 superclass 指向 根类的元类 根元类的 superclass 指向 根类 根类的 superclass 指向 nil。

示例

 int main(int argc, const char * argv[]) {@autoreleasepool {//iskindOfClass & isMemberOfClass 类方法调用BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];BOOL re2 = [(id)[Person class] isKindOfClass:[Person class]];BOOL re3 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];BOOL re4 = [(id)[Person class] isMemberOfClass:[Person class]];NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);//iskindOfClass & isMemberOfClass 实例方法调用BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];BOOL re6 = [(id)[Person alloc] isKindOfClass:[Person class]];BOOL re7 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];BOOL re8 = [(id)[Person alloc] isMemberOfClass:[Person class]];NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);}return 0;
}

运行的结果:
在这里插入图片描述

源码解析:

isKindOfClass:源码解析(实例方法和类方法)

//--isKindOfClass---类方法、对象方法
//+ isKindOfClass:第一次比较是 获取类的元类 与 传入类对比,再次之后的对比是获取上次结果的父类 与 传入 类进行对比
+ (BOOL)isKindOfClass:(Class)cls {// 获取类的元类 vs 传入类// 根元类 vs 传入类// 根类 vs 传入类// 举例:LGPerson vs 元类 (根元类) (NSObject)for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {if (tcls == cls) return YES;}return NO;
}//- isKindOfClass:第一次是获取对象类 与 传入类对比,如果不相等,后续对比是继续获取上次 类的父类 与传入类进行对比
- (BOOL)isKindOfClass:(Class)cls {
/*
获取对象的类 vs 传入的类 
父类 vs 传入的类
根类 vs 传入的类
nil vs 传入的类
*/for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {if (tcls == cls) return YES;}return NO;
}

isMemberOfClass:源码解析(实例方法和类方法)

//类方法
//+ isMemberOfClass : 获取类的元类,与 传入类对比
+ (BOOL)isMemberOfClass:(Class)cls {return self->ISA() == cls;
}
//实例方法
//- isMemberOfClass : 获取对象的类,与 传入类对比
- (BOOL)isMemberOfClass:(Class)cls {return [self class] == cls;
} 

源码分析总结:

isKindOfClass:

类方法:元类 --> 根元类 --> 根类 --> nil 与 传入类的对比。
实例方法:对象的类 --> 父类 --> 根类 --> nil 与 传入类的对比。

isMemberOfClass:

类方法: 类的元类 与 传入类对比。
实例方法:对象的父类 与 传入类对比。

通过上面的源码解析分析代码:

ret1 = 1,传入的cls为NSObject,self指的是NSObject,进入循环。 第一次循环:是NSObject meta与NSobject进行比较,不相等,tcls = tcls->superclass ,此时 tcls 指向 NSobject meta 的父类 ,即 NSObject。进入第二次循环。 第二次循环:此时 tcls 为 NSobject,cls 依然是 NSobject,执行判断条件 if (tcls == cls) 相等,return YES。
所以 re1 的结果为 1。

ret2 = 0,传入的cls为Person,self指的是Person,进入循环 第一次循环:tcls为Person meta,cls为Person类;不相等,执行tcls = tcls->superclass, 此时 tcls 指向 NSobject metal。进入第二次循环。 第二次循环:tcls 为 NSobject meta ,cls 为 Person类;不相等,执行 tcls = tcls->superclass ,此时 tcls 指向 NSObject。进入第三循环。 第三次循环: tcls 为 NSobject ,cls 为 Person类;不相等,执行 tcls = tcls->superclass ,此时 tcls 指向 nil。不满足for循环执行条件 tcls。结束循环。
所以 re2 的结果为 0。

ret3 = 0 : 传入的cls 为 NSObject, self 指向 NSObject
self->ISA( ) ,self的 isa 指向 NSObject meta ;NSObject meta 与 NSObject 不相等。
所以 re3 的结果为 0。

ret4 = 0 : 传入的cls 为 Person, self 指向 Person
self->ISA( ) ,self的 isa 指向 Person meta ;Person meta 与 Person 不相等。
所以 re4 的结果为 0。

ret5 = 1 : 传入的cls 为 NSObject 类,self 指向 NSObject 的 实例对象
第一次循环:tcls 指向 NSObject 类,cls 为 NSObject 类,执行判断 if (tcls == cls) ,相等,return YES,结束循环。
所以 re5 返回 1。

ret6 = 1 : 传入的cls 为 Person 类,self 指向 Person 的 实例对象
第一次循环:tcls 指向 Person 类,cls 为 Person 类,执行判断 if (tcls == cls) ,相等,return YES,结束循环。
所以 re6 返回 1。

ret7 = 1 : 传入的cls 为 NSObject, self 指向 NSObject 对象
[self class] 为 NSObject 类 ;与 cls 相等。
所以 re7 的结果为 1。

ret8 = 1 : 传入的cls 为 Person, self 指向 Person 对象
[self class] 为 Person 类 ;与 cls 相等。
所以 re8 的结果为 1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/48065.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【中项】系统集成项目管理工程师-第2章 信息技术发展-2.2新一代信息技术及应用-2.2.3大数据与2.2.4区块链

前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…

@Configuration的proxyBeanMethods

作用:用于控制配置类的代理行为,确定配置类中的 Bean 方法是否被代理,从而影响 Bean 的创建和管理方式 比较 proxyBeanMethods true 默认行为: 当 proxyBeanMethods 设置为 true(默认值)时,Spring 会为配置类创建一…

HTML进阶:探索语义化标记与可访问性优化

随着Web技术的不断发展,HTML不再仅仅是用来定义网页内容的标记语言,它还被赋予了更多的责任,如提高网页的可读性、可维护性和可访问性。语义化标记(Semantic Markup)和可访问性优化(Accessibility Optimiza…

航班管理系统【C语言版】单文件编写

开发环境 操作系统:Windows 11专业版开发工具:Visual Studio Code编程语言:C 项目考核验收表 1. 设计目标 本项目的目标是设计并实现一个简易的航班管理系统。该系统应具备以下功能: 添加航班信息查询航班信息显示所有航班信…

自动标签的艺术:sklearn中的聚类标签自动分配技术

自动标签的艺术:sklearn中的聚类标签自动分配技术 在机器学习领域,聚类是一种无监督学习方法,它将数据集中的样本分组,使得同一组内的样本相似度高,而不同组之间的样本相似度低。与有监督学习不同,聚类不依…

前端经验:使用sheetjs导出CSV文本为excel

应用场景 很多web表格组件没有提供直接的导出excel功能,但提供了导出CSV的功能。 如果能想办法拿到CSV的内容,就可以利用sheetjs生成excel并导出。 实施步骤 1.拿到CSV的内容字符 每种表格组件都有各自的CSV生成方法,不管用什么方法&…

[python] 利用opencv显示对比试验效果

利用 opencv 显示 对比实验效果 选择有效区域 import os import random import uuidfrom tqdm import tqdm import cv2 import numpy as np import matplotlib.pyplot as plt GT_Dir"results_compare/GT/" Bicubic_dir"results_compare/Bicubic4x/" Phase…

服务器证书基于 OpenSSL一键颁发脚本

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

vue使用了代理跨域,部署上线,使用Nginx配置出现问题,访问不到后端接口

1、如果路由的mode是history模式的要加上框框里的哪句,然后配置下面的location router location / {root /usr/local/app/dist/; #vue文件dist的完整路径try_files $uri $uri/ router;index index.html index.htm;}#error_page 500 502 503 504 /50x.html;lo…

数据分析入门指南:数据库入门(五)

本文将总结CDA认证考试中数据库中部分知识点,内容来源于《CDA模拟题库与备考资料PPT》 。 CDA认证,作为源自中国、面向全球的专业技能认证,覆盖金融、电信、零售、制造、能源、医疗医药、旅游、咨询等多个行业,旨在培养能够胜任数…

RK3328 Debian安装OpenMediaVault

手头有RK3328板卡,自己编译了Debian并烧录跑起来了,拿它来作为NAS使用,在网上找了一些开源的NAS系统,最终敲定使用OpenMediaVault这套,下面是在RK3328 Debian系统下的安装过程: 0、先打开一个Terminal终端…

CVE-2023-33440(任意文件上传)

简介 Faculty Evaluation System v1.0 存在未授权任意文件上传漏洞漏洞 过程 打开靶场 进行目录扫描 发现后台login.php,进入查看 弱口令进行测试,无效,无法进入 根据提示是未授权访问文件上传 ,应该是不需要登录就能触发漏洞…

分布式Session共享的5类技术方案,与优劣势比较

分布式Session共享是分布式系统中常见的问题,主要解决在多个服务器之间共享用户会话信息的需求。以下是五种常见的分布式Session共享技术方案及其优劣势比较: 1. Session复制 设计思路: 多个Web服务器之间相互同步Session,每个W…

Apple Vision Pro 开发资源大全

Apple Vision Pro 是一款强大的视觉处理设备,为开发者提供了丰富的应用场景和开发资源。以下是与 Apple Vision Pro 相关的应用程序、开发者资源、社区和文章的集合,旨在帮助开发者更好地利用这一平台。 1. Vision Pro 使用技巧 技巧和窍门:提供一系列实用的使用技巧,帮助…

http 协议中GET如何传递参数(Query String)?

因为项目需要,最近在手搓一个Http Connection,目的是实现最简单的Http访问,能通过Get或则Post方法向数数的日志服务器传递数据。之前看过数数提供的开发包,因为服务器用的是C,而数数提供的C/C开发包简陋的吓人&#xf…

openstack设置IP直接登录,不需要加dashboard后缀

openstack 实验环境,openstack-t版,centos2009 修改配置文件 [rootcontroller ~]# vim /WEBROOT /etc/openstack-dashboard/local_settings #将dashboard去掉 WEBROOT /dashboard/ #改为 WEBROOT /[rootcontroller ~]# vim /etc/httpd/conf.d/openst…

深度学习每周学习总结N4:中文文本分类-Pytorch实现(基本分类(熟悉流程)、textCNN分类(通用模型)、Bert分类(模型进阶))

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 目录 0. 总结:1. 基础模型a. 数据加载b. 数据预处理c. 模型搭建与初始化d. 训练函数e. 评估函数f.拆分数据集运行模型g. 结果可…

C++STL初阶(7):list的运用与初步了解

在了解了vector之后,我们只需要简单学习List与vector不一样的接口即可 1.list的基本接口 1.1 iterator list中,与vector最大的区别就是迭代器由随机迭代器变成双向迭代器 string和vector中的迭代器都是随机迭代器,支持-等,而LIS…

达梦数据库 MPP集群搭建(带主备)

MPP集群搭建(带主备) 1.背景2.操作内容和要求3. 具体步骤3.1 搭建过程3.1.1 集群搭建3.1.2 准备工作3.1.2.1 初始化3.1.2.2 备份数据库 3.1.3 配置主库EP013.1.3.1 配置dm.ini3.1.3.2 配置dmmal.ini3.1.3.3 配置dmarch.ini3.1.3.4 配置dmmpp.ctl3.1.3.5 …

Seata 面试题及答案整理,最新面试题

Seata 是如何解决分布式事务问题的? Seata通过事务协调器、事务管理器和资源管理器三个核心组件来解决分布式事务问题。 1、事务协调器(TC): TC作为全局事务的协调者,负责维护全局和分支事务的状态,并协调全局提交或回滚。 2、事务管理器(TM): TM负责定义全局事务的范…