iOS isKindOfClass isMemberOfCla
2020-08-05 本文已影响0人
fordG
- 看了一下runtime记录一下
下面代码运行结果
@interface Sark : NSObject
@end
@implementation Sark
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];
BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];
NSLog(@"%d %d %d %d", res1, res2, res3, res4);
}
return 0;
}
-
在Object-C中类大部分都是继承自NSObject
-
我们在调试的过程中发现, isa这个指针
image.png -
在runtime中看源码
/// A pointer to an instance of a class.
typedef struct objc_object *id;
struct objc_object {
Class isa;
}
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
//在 objc-runtime-new.h 中
struct objc_class : objc_object {
// Class ISA;
Class superclass;
...
...
}
- 对象是一个obj_object类型的结构体
- 通过上面的代码发现 我们 new 了一个对象,这个对象内部会生产isa指针, 这个指针是指向对象的类,我们就是用这个类来初始化对象的(objc_object)。
- isa指针指向的是一个Class类,它的定义是一个ob j_class的结构体,里面存放了很多累的方法成员变量协议等信息, 这里面也有一个isa指针,指向的是这个类的类,从objc_class : objc_object可以看出来, 对象的类本质上也是一个对象, 这里面有一个superclass举个列子分析啊一下
@interface Person : NSObject
@end
@implementation Person
@end
我们初始化一个Person对象
Person *person = [Person new]
person对象里面有个isa指针指向Person这个类对象
Person类对象里面有个isa指针指向Person这个类对象的类, 这个类我们叫做Meta Class 元类
Person类对象的Meta Class 里面有个superClass我们可以person的父类里面去找他的父类的Meta Class就是Person类对象的isa指针指向的Meta Class的superClass
image.png
- 最上层的Meta Class的isa指针指向自己,形成一个回路
- 最上层的NSObject Class的super class指向 nil
理清楚对象和类对象和元类的关系后再看源码
+ (Class)class {
return self;
}
- (BOOL)isKindOf:aClass
{
Class cls;
for (cls = isa; cls; cls = cls->superclass)
if (cls == (Class)aClass)
return YES;
return NO;
}
- (BOOL)isMemberOf:aClass
{
return isa == (Class)aClass;
}
- class 返回的类对象本身
- isKindOf中,我们用类对象本身去和aClass比较, 可以看到首先会拿这个类对象的isa指向的Meta Class 和传入的aClass比较,然后在取Meta Class的superClass再比较一次,然后返回结果
- isMemberOf直接用方法调用对象的isa指向的类对象来和aClass比较
题目中 [(id)[NSObject class] isKindOfClass:[NSObject class]]
方法调用者是[NSObject class] 即NSObject类对象isa指向的MetaClass和[NSObject class]不是同一个,第二次比较的是[NSObject class] 的M etaClass指向的superClass(看上面的图片指向的是[NSObject class] ) 和 [NSObject class] 比较相等,
[(id)[NSObject class] isMemberOfClass:[NSObject class]] 只比较上面的第一步, 所以不想等
[(id)[Sark class] isKindOfClass:[Sark class]]; 这个第二部,没有Sark的MetaClass 的superClass指向的是Sark的父类的MetaClass, 所以不可能相等
[(id)[Sark class] isMemberOfClass:[Sark class]] 同理不想等