【iOS】isKindOfClass和isMemberOfClass方法
前言
这个归根结底还是在考察我们对isa走向图和类的继承的理解,也就是苹果官方这幅图:

接下来的函数调用流程请参考这张图。
1 isKindOfClass方法
1.1 objc_opt_isKindOfClass C函数
查看源码可发现,无论是谁调用isKindOfClass方法都会进入这个C函数。(这个C函数位于NSObjective.mm)
// Calls [obj isKindOfClass]
// 当obj调用isKindOfClass时,objc_opt_isKindOfClass会被触发
// obj是一个id类型,id是一个objc_object结构体指针,意味着,传进来的可以是时类,也可以是类的实例对象
// otherClass就是isKindOfClass的参数,我们当初传进去的cls
BOOL objc_opt_isKindOfClass(id obj, Class otherClass)
{
#if __OBJC2__if (slowpath(!obj)) return NO;Class cls = obj->getIsa(); // 此处的cls仅是obj的第一个isaif (fastpath(!cls->hasCustomCore())) {// otherClass 从obj的ISA开始,依次和ISA的父类比较,直到找到或者父类为nil结束// 当父类为nil意味着最后一个和otherClass比较的是NSObject根类。for (Class tcls = cls; tcls; tcls = tcls->superclass) {if (tcls == otherClass) return YES;}return NO;}
#endifreturn ((BOOL(*)(id, SEL, Class))objc_msgSend)(obj, @selector(isKindOfClass:), otherClass);
}
可知:
- 一切皆从调用者
obj的isa开始,然后顺着superclass走下去,直到找到cls或superclass为nil结束。 - 当
superclass为nil,意味着最后的根类NSObject也不是cls,返回flase。
1.2 类SubClass调用+ (BOOL)isKinsOfClass:(Class)cls
流程:
- 从类的
isa——元类开始,判断它不是cls; - 如果是,返回
true; - 如果不是,继续用元类的
superclass和cls比较,看是不是cls; - 直到根类
NSObject也比较完。
判断顺序: SubClass与 MetaClass->MetaClass->...->RootMetaClass->NSObject。
总结:
- 判断
cls是不是 元类->父类的元类->父父类的元类->…->根元类->NSObject(元类的superclass继承链)其中一个。 cls传除NSObject.class外的任意类对象均为false。
1.3 元类MetaClass 调用+ (BOOL)isKinsOfClass:(Class)cls
流程:
MetaClass的ISA指向RootMetaClass,所以从RootMetaClass开始比较判断是不是我们传入的cls;- 如果不是,再看根类
NSObject是不是,如果NSObject也不是,就彻底没有了,返回false。
判断顺序:MetaClass 与 RootMetaClass->NSObject。
总结:
- 判断
cls是不是根元类->NSObject中的任意一个。
1.4 对象obj 调用- (BOOL)isKinsOfClass:(Class)cls
流程:
- 从
isa指向的类对象开始,判断是不是cls; - 如果不是,看类对象的父类,逐级判断是不是
cls; - 直到找到返回
true,或者判断到NSObject依然不是,返回false结束。
判断顺序: object 与 SubClass -> SubClass ->...->NSObject。
总结:
- 判断cls是不是 类对象->父类->…->NSObject (superclass继承链)其中一个。
2 isMemberOfClass
2.1 类对象SubClass调用+ (BOOL)isMemberOfClass
源码:
+ (BOOL)isMemberOfClass:(Class)cls {return self->ISA() == cls;
}
不用像isKindOfClass循环直到找到或nil,他只要比较cls是不是我当前的isa指向,是返回true,不是返回false。
判断:SubClass与MetaClass。
2.2 元类MetaClass 调用+ (BOOL)isMemberOfClass
因为元类的isa只指向根元类NSObejct ,所以除了NSObject的类SubClass以外,传入任何类对象也都是false。
验证传入NSObject的类SubClass的结果:
void demo(void) {
// BOOL re1 = [[NSObject class] isKindOfClass:[NSObject class]];Class rootMetaClass = object_getClass([NSObject class]);NSLog(@"%d", [[NSObject class] isMemberOfClass:rootMetaClass]);
}
结果:

2.3 对象obj调用 -(BOOL)isMemberofClass:(Class)clss
- (BOOL)isMemberOfClass:(Class)cls 底层源码:
- (BOOL)isMemberOfClass:(Class)cls {return [self class] == cls;
}
- (Class)class {return object_getClass(self); // 获取当前的isa指向的类
}
只要判断对象的isa,也就是图中的SubClass是不是我们传入的cls。
3. 测试
void demo(void) {BOOL f1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];BOOL f2 = [(id)[MyClass class] isKindOfClass:[MyClass class]];BOOL f3 = [(id)[MySuperClass class] isKindOfClass:[MySuperClass class]];BOOL f4 = [(id)[MyClass class] isKindOfClass:[MySuperClass class]];BOOL f5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];BOOL f6 = [(id)[MyClass alloc] isKindOfClass:[NSObject class]];BOOL f7 = [(id)[MySuperClass alloc] isKindOfClass:[NSObject class]];NSLog(@"NSObjectClass ISKindOf NSObjectClass:%d", f1);NSLog(@"MyClassClass ISKindOf MyClassClass:%d", f2);NSLog(@"MySuperClassClass ISKindOf MySuperCassClass:%d", f3);NSLog(@"MyClassClass ISKindOf MySuperClassClass:%d", f4);NSLog(@"NSObjectObj ISKindOf NSObjectClass:%d", f5);NSLog(@"MyClassObj ISKindOf NSObjectClass:%d", f6);NSLog(@"MySuperClassObj ISKindOf NSObjectClass:%d", f7);}
测试结果:

相关文章:
【iOS】isKindOfClass和isMemberOfClass方法
前言 这个归根结底还是在考察我们对isa走向图和类的继承的理解,也就是苹果官方这幅图: 接下来的函数调用流程请参考这张图。 1 isKindOfClass方法 1.1 objc_opt_isKindOfClass C函数 查看源码可发现,无论是谁调用isKindOfClass方法都会…...
李飞飞「具身智能」VoxPoser:0预训练完成复杂指令
机器人接入大模型听懂人话 论文地址: https://voxposer.github.io/voxposer.pdf 项目主页: https://voxposer.github.io/ 参考链接: [1]https://twitter.com/wenlong_huang/status/1677375515811016704 [1]https://www.amacad.org/publicatio…...
前端八股文
info 毕业设计(课题、方向 本科毕业设计:家庭医生签约管理系统后台开发(微信小程序) 硕士课题:医学图像分割(婴儿脑分割) 51062319991129351X 邮编 重庆市南岸区 400000 13183849783 // 18728097929 // 13158442955 中国广电四川网络股份有限公司中江…...
前端年度工作述职报告优秀
前端年度工作述职报告优秀篇1 尊敬的各位领导、各位同仁: 大家好!按照20__年度我公司就职人员工作评估的安排和要求,我认真剖析、总结了自己的工作情况,现将本人工作开展情况向各位领导、同仁做以汇报,有不妥之处,希…...
【MyBatis 学习一】认识MyBatis 第一个MyBatis查询
目录 一、认识MyBatis 1、MyBatis是什么? 2、为什么要学习MyBatis? 二、配置MyBatis环境 1、建库与建表 2、创建新项目 3、xml文件配置 (1)配置数据库连接 (2)配置 MyBatis 中的 XML 路径 三、测试&#x…...
TCP 和 UDP
TCP(Transmission Control Protocol,传输控制协议) 是面向连接的协议,即在收发数据前,必须和对方建立可靠的连接,TCP的头部为20个字节。 UDP(User Datagram Protocol,用户数据报协…...
springboot配置自定义数据源(Druid德鲁伊)的步骤。
今天和大家分享下在Springboot中配置自定义数据源Druid的两种方法及步骤。 方法一: 1.在pom.xml配置依赖(注释里面的内容) 2.配置自己的数据源设置,我是在yaml文件中配置的,顺便提醒一下,在配置yaml文件的时候缩进问题一定要注意…...
K8S:容器日志收集与管理
Kubernetes 里面对容器日志的处理方式,都叫作 cluster-level-logging,即:这个日志处理系统,与容器、Pod 以及 Node 的生命周期都是完全无关的。这种设计当然是为了保证,无论是容器挂了、Pod 被删除,甚至节点…...
Flutter系列文章-Flutter进阶
在前两篇文章中,我们已经了解了Flutter的基础知识,包括Flutter的设计理念、框架结构、Widget系统、基础Widgets以及布局。在本文中,我们将进一步探讨Flutter的高级主题,包括处理用户交互、创建动画、访问网络数据等等。为了更好地…...
【C++】C++11右值引用|新增默认成员函数|可变参数模版|lambda表达式
文章目录 1. 右值引用和移动语义1.1 左值引用和右值引用1.2 左值引用和右值引用的比较1.3右值引用的使用场景和意义1.4 左值引用和右值引用的深入使用场景分析1.5 完美转发1.5.1 万能引用1.5.2 完美转发 2. 新的类功能2.1 默认成员函数2.2 类成员变量初始化2.3 强制生成默认函数…...
rust学习-线程
Rust 标准库只提供了 1:1 线程模型 Rust 是较为底层的语言,如果愿意牺牲性能来换取抽象,以获得对线程运行更精细的控制及更低的上下文切换成本,使用实现了 M:N 线程模型的 crate 示例 use std::thread; use std::time::Duration;fn main() …...
题目:2180.统计各位数字之和为偶数的整数个数
题目来源: leetcode题目,网址:2180. 统计各位数字之和为偶数的整数个数 - 力扣(LeetCode) 解题思路: 暴力遍历即可。 解题代码: class Solution {public int countEven(int num) {int re…...
3dsmax制作一个机器人
文章目录 建模身子:眼睛:头饰:肩膀手臂腿调整细节 渲染导出objMarmoset Toolbag 3.08渲染给眼睛添加材质,设置为自发光添加背景灯光 建模 身子: 眼睛: 头饰: 肩膀 手臂 腿 调整细节 渲染 导出…...
C++的类型转换运算符:reinterpret_cast
C的类型转换运算符:reinterpret_cast reinterpret_cast 是 C 中与 C 风格类型转换最接近的类型转换运算符。它让程序员能够将一种对象类型转换为另一种,不管它们是否相关;也就是说,它使用如下所示的语法强制重新解释类型…...
flask中的cookies介绍
flask中的cookies介绍 “Cookie” 在 web 开发中是一种非常重要的技术,用于在客户端(即用户的浏览器)存储信息,以便在多个页面和多个访问会话之间保持状态。Cookies 通常用于记住用户的登录信息,跟踪用户在站点上的浏…...
adnroid 11. 0 Activity启动流程图解
从Launcher到ActivityTaskManager 从ActivityTaskManagerService 到 ApplicationThread 从ApplicationThread到onCreate...
了解Unity编辑器之组件篇Physics(四)
Physics:用于处理物理仿真和碰撞检测。它提供了一组功能强大的工具和算法,用于模拟真实世界中的物理行为,使游戏或应用程序更加真实和可信。 主要用途包括: 碰撞检测:Unity Physics 提供了高效的碰撞检测算法&#x…...
“数字中华 点亮未来”中华线上客户节 盛大开幕
2023年是中华保险数字化转型落地之年,峥嵘37载,中华保险在数字化转型上已经涌现了一批彰显辨识度、具有影响力的应用成果。7月15日,中华保险围绕数字化转型之路开展以“数字中华 点亮未来”为主题的37周年线上客户节活动,倾力打造…...
中文分词入门:使用IK分词器进行文本分词(附Java代码示例)
1. 介绍 中文分词是将连续的中文文本切分成一个个独立的词语的过程,是中文文本处理的基础。IK分词器是一个高效准确的中文分词工具,采用了"正向最大匹配"算法,并提供了丰富的功能和可定制选项。 2. IK分词器的特点 细粒度和颗粒…...
CTFSHOW web 信息收集
web入门的刷题 web1 教我们多看看源代码 web2 抓包 web3 抓包 web4 robots.txt robots.txt web5 phps源代码泄露 phps 就是php的源代码 用户无法访问 php 只可以通过phps来访问 web6 源代码备份 web7 git web8 svn web9 swp /index.php.swp web10 cookie web11 查域名…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
