isMemberOfClass

- 调用者必须是传入的类的实例对象才返回YES
- 判断调用者是否是传入对象的实例,别弄反了,如 [s1 isMemberOfClass:p1] ,意思是s1是否是p1的实例对象
- 不进行父类递归去查找判断

源码:

+ (BOOL)isMemberOfClass:(Class)cls {
return object_getClass((id)self) == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}

有两个方法,一个实例方法,一个类方法,两者区别:

- 实例方法:是根据实例对象取得类对象,再去判断
 - 类方法:是根据对象取得元类对象,再去判断

实例代码:

XPerson* p1 = [[XPerson alloc]init];
XStudent* s1 = [[XStudent alloc]init]; // true (用s1的类对象和 [s1 class] 判断,肯定是一样的了)
NSLog(@"s1是否是s1 实例: %i",[s1 isMemberOfClass:[s1 class]]);
// true ([s1 class] 与 [XStudent class] 等同,一个类只会有一个类对象,一个元类对象,可以有多个实例对象)
NSLog(@"s1是否是XStudent 实例: %i",[s1 isMemberOfClass:[XStudent class]]);
// false (s1的类对象 != p1的类对象)
NSLog(@"s1是否是p1 实例: %i",[s1 isMemberOfClass:[p1 class]]);
// false (同上)
NSLog(@"s1是否是XPerson 实例: %i",[s1 isMemberOfClass:[XPerson class]]); // false (XStudent元类对象 != XStudent类对象)(底层是获取XStudent的元类去比较)
NSLog(@"XStudent是否是XStudent 实例: %i",[XStudent isMemberOfClass:[XStudent class]]);
// true (XStudent元类对象 = XStudent元类对象)
NSLog(@"XStudent是否是XStudent元类 实例: %i",[XStudent isMemberOfClass:object_getClass([XStudent class])]);
// false (XStudent元类对象 != XPerson元类对象)
NSLog(@"XStudent是否是XPerson元类 实例: %i",[XStudent isMemberOfClass:objet_getClass([XPerson class])]);

isKindOfClass

- 调用者是传入的类的实例对象,或者调用者是传入类的继承者链中的类的实例对象,则返回YES
- 判断调用者是否是传入对象的子类,别弄反了
- 去父类递归查找判断

源码:

+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->super_class) {
if(tcls == cls) return YES;
}
return NO;
}
-(BOOL)isKindOfClass:(Class)cls {
for(Class tcls = [self class]; tcls; tcls = tcls->super_class) {
if(tcls == cls) return YES;
}
return NO;
}

实例代码:

XPerson* p1 = [[XPerson alloc]init];
XStudent* s1 = [[XStudent alloc]init]; // true (用s1的类对象、父类类对象、基类类对象([NSObject class]) 去和 p1的类对象比较,[p1 class]是s1的父类类对象)
NSLog(@"s1是否是p1 子类: %i",[s1 isKindOfClass:[p1 class]]);
// true (同上:[XPerson class] 与 [p1 class]是等同的)
NSLog(@"s1是否是XPerson 子类: %i",[s1 isKindOfClass:[XPerson class]]);
// true ([NSObject class]是s1的基类类对象)
NSLog(@"s1是否是NSObject 子类: %i",[s1 isKindOfClass:[NSObject class]]); // false (用 XStudent的元类、父元类、基类(NSObject类对象) 去与 XPerson的对象比较)
NSLog(@"XStudent是否是XPerson 子类: %i",[XStudent isKindOfClass:[XPerson class]]);
// true (类方法需要传入 元类进去判断,里面会取 XStudent 元类去比较)
NSLog(@"XStudent是否是XPerson元类 子类: %i",[XStudent isKindOfClass:object_getClass([XPerson class])]);
// true (元类的最上层就是基元类)
NSLog(@"XStudent是否是NSObject元类 子类: %i",[XStudent isKindOfClass:object_getClass([NSObject class])]);

isMemberOfClass、isKindOfClass原理分析的更多相关文章

  1. WebViewJavascriptBridge 原理分析

    WebViewJavascriptBridge 原理分析 网上好多都是在介绍 WebViewJavascriptBridge如何使用,这篇文章就来说说 WebViewJavascriptBridge ...

  2. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  3. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  4. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  5. Android中Input型输入设备驱动原理分析(一)

    转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...

  6. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  7. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

  8. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

  9. 使用AsyncTask异步更新UI界面及原理分析

    概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...

随机推荐

  1. 智能小程序关于Filter过滤器的简单使用

    <filter module="swan"> export default { imgurl: (imgUrl) => { var imgurlprefix = ...

  2. spring 5.x 系列第4篇 —— spring AOP (代码配置方式)

    文章目录 一.说明 1.1 项目结构说明 1.2 依赖说明 二.spring aop 2.1 创建待切入接口及其实现类 2.2 创建自定义切面类 2.3 配置切面 2.4 测试切面 2.5 切面执行顺 ...

  3. tomcat源码分析(一)- tomcat源码导入IDEA并正常启动

    项目导入 代码下载 打开GitHub网站:https://github.com/apache/tomcat 下载对应的zip包 解压对应的压缩包(当然你也可以用工具对其进行解压) unzip tomc ...

  4. Python批量自动裁剪图片

    """用Pythonp批量裁剪图片""" from PIL import Image import matplotlib.pyplot as ...

  5. 【Linux】一步一步学Linux——VMware虚拟机三种网络模式详解(07)

    目录 00. 目录 01. 虚拟网络连接组件 02. 常见网络连接配置 03. 桥接模式 04. NAT 模式 05. 仅主机模式 06. 自定义模式 07. 附录 00. 目录 @ 01. 虚拟网络 ...

  6. RT-Thread的CPU占用率查看

    今天看到朋友的博客,他在描述RT-Thread钩子函数时,简单提了下RT-Thread中CPU占用,没有具体描述,所以我在这里做下补充. RT-Thread查看CPU使用率时,我知道的有这种方法. 大 ...

  7. black box黑盒测试

    软件规格说明书 等价类划分,完备性,无冗余性(不能有交集).   健壮等价类:无效等价类 边界值分析,对于一个含有n个变量的程序,采用边界值分析法测试程序会产生4n+1个测试用例           ...

  8. c++学习书籍推荐《The C++ Programming Language第四版》下载

    百度云及其他网盘下载地址:点我 作者简介 Bjarne Stroustrup is the designer and original implementer of C++, the author o ...

  9. ElasticStack学习(七):ElasticSearch之Mapping初探

    一.Mapping的概念 1.Mapping类似于数据库中的Schema的定义,作用如下: 1)定义索引中的字段的名称: 2)定义字段的数据类型,例如字符串.数字.日期.布尔等: 3)对每个字段进行倒 ...

  10. 彻底搞清楚c#中的委托和事件

    一.什么是委托呢? 听着名字挺抽象,确实不好理解.面试官最喜欢考察这个,而且更喜欢问:“委托和事件有何异同?”.如果对一些知识点没有想明白,那么很容易被绕进去.研究任何事物,我们不妨从它的定义开始,委 ...