什么是内省?
在计算机科学中,内省是指计算机程序在运行时(Run time)检查对象(Object)类型的一种能力,通常也可以称作运行时类型检查。 不应该将内省和反射混淆。
相对于内省,反射更进一步,是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。
内省的几个方法
isMemberOfClass
//对象是否是某个类型的 对象
isMemberOfClass的源码实现是拿到自己的isa指针和自己比较,是否相等。
isKindOfClass
//对象是否是某个类型或某个类型子类的 对象
- (BOOL)isKindOfClass:(Class)cls方法内部,会先去获得object_getClass的类,而object_getClass的源码实现是去调用当前类的obj->getIsa(),最后在ISA()方法中获得meta class的指针。
isSubclassOfClass
//某个类对象 是否是另一个类型的子类
isAncestorOfObject
//某个类对象 是否是另一个类型的父类
respondsToSelector
//是否能响应某个方法
conformsToProtocol
//是否遵循某个协议
isKindOfClass 与 isMemberOfClass
@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;
}
//1 0 0 0
在isKindOfClass中有一个循环,先判断class是否等于meta class,不等就继续循环判断是否等于super class,不等再继续取super class,如此循环下去。
接着也要用到这么一张图
-
[NSObject class]执行完之后调用isKindOfClass,第一次判断先判断NSObject 和 NSObject的meta class是否相等,之前讲到meta class的时候放了一张很详细的图,从图上我们也可以看出,NSObject的meta class与本身不等。
-
接着第二次循环判断NSObject与meta class的superclass是否相等。还是从那张图上面我们可以看到:Root class(meta) 的superclass 就是 Root class(class),也就是NSObject本身。所以第二次循环相等,于是第一行res1输出应该为YES。
-
同理,
[Sark class]
执行完之后调用isKindOfClass
,第一次for
循环,Sark
的Meta Class
与[Sark class]
不等,第二次for循环
,Sark
Meta Class的super class
指向的是NSObject Meta Class
, 和Sark Class
不相等。 -
第三次for循环,
NSObject Meta Class
的super class
指向的是NSObject Class
,和Sark Class
不相等。第四次循环,NSObject Class
的super class
指向nil
, 和Sark Class
不相等。第四次循环之后,退出循环,所以第三行的res3输出为NO
。 -
如果把这里的Sark改成它的实例对象,
[sark isKindOfClass:[Sark class]
,那么此时就应该输出YES
了。因为在isKindOfClass
函数中,判断sark的meta class
是自己的元类Sark
,第一次for循环就能输出YES
了。 -
isMemberOfClass
的源码实现是拿到自己的isa指针
和自己比较,是否相等。 -
第二行
isa
指向NSObject
的Meta Class
,所以和NSObject Class
不相等。第四行,isa
指向Sark
的Meta Class
,和Sark Class
也不等,所以第二行res2
和第四行res4
都输出NO。
网友评论