咱们在开发中常常会用到 isKindOfClass:
来判断一个 obj
是否是某个类型。 咱们全部的知识点都基于“类”的isamarkdown
isKindOfClass:
查看objc4源码,咱们会看到,不管是谁调用isKindOfClass:
都会进入objc_opt_isKindOfClass
C函数。函数
这个C函数位于NSObject.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的第一个isa
if (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;
}
#endif
return ((BOOL(*)(id, SEL, Class))objc_msgSend)(obj, @selector(isKindOfClass:), otherClass);
}
复制代码
获得一个信息:ui
在isa走位图的基础上,分析不一样状况时,cls的比较判断路径:spa
类
调用 + (BOOL)isKinsOfClass:(Class)cls用isa走位图来表示,蓝色部分就是cls依次比较的链路。3d
类对象SubClass
调用isKindOfClass 文字描述:指针
判断顺序: SubClass -> MetaClass->MetaClass->...->RootMetaClass->NSObject
code
其中, 类对象调用方法的本质 是判断 cls
是否是 元类的继承链
上的任意一个orm
元类MetaClass
调用isKindOfClass仍是上图, MetaClass
的 ISA
指向 RootMetaClass
,因此从 RootMetaClass
开始比较判断是否是咱们传入的cls,若是不是,再看根类NSObject是否是,若是NSObject也不是,就完全没有了,返回false,对象
cls判断顺序如图:MetaClass ->
RootMetaClass->NSObject
对象obj
调用- (BOOL)isKinsOfClass:(Class)cls从isa指向的类对象开始,判断是否是cls;若是不是,看类对象的父类,逐级判断是否是cls;直到找到返回true,或者判断到NSObject依然不是,返回false结束。
cls判断顺序如图所示:object ->
SubClass -> SubClass ->...->NSObject
本质是判断 cls
是否是 类继承链
上的任意一个
isMemberofClass
类
调用 +(BOOL)isMemberofClass:(Class)clss+ (BOOL)isMemberOfClass:(Class)cls
底层源码
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
复制代码
不用像isKindOfClass循环直到找到或nil,他只要比较cls是否是我当前的isa指向,是返回true,不是返回false。
这个方法单纯地用来判断,cls是否是调用者的isa !!
类对象SubClass
调用isMemberofClass :传入任何类对象都是false由于类的isa不指向类对象 ,参见下图
元类MetaClass
调用isMemberofClass:传入任何类对象也都是false对象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
类对象SubClass
:+(BOOL)isKindOfClass:(Class)cls
:
cls
传除NSObject.class外的任意类对象均为false。+(BOOL)isMemeberOfClass:(Class)cls
:
元类MetaClass
:+(BOOL)isKindOfClass:(Class)cls
:
+(BOOL)isMemeberOfClass:(Class)cls
:
对象Obj
:-(BOOL)isKindOfClass:(Class)cls
:
-(BOOL)isMemeberOfClass:(Class)cls
:
cls
是否是本身的 类(类对象)