获取Class

2018-02-09 12:48:48来源:https://www.jianshu.com/p/64516fed438b作者:学习路上一个远行者人点击

分享


Class

class本质是一个结构体的指针,结构体是objc_class,这个结构体中包含了:


isa (实例->类->meta 类->root meta 类)root meta类指向本身
父类型的指针
类的名字
方法列表(可以是实例方法列表,也可以是类方法列表)
实现的协议列表
版本
保留的信息
id

id 本质也是一个结构体的指针,结构体是objc_object这个结构体中包含:
struct objc_object { Class isa OBJC_ISA_AVAILABILITY; }


两个获取class的方法:

+(Class)class
这是一个类方法,源码是:
+ (Class)class { return self; }
类方法的class是指向的自己本身,也许你在别人的代码中看见这样的一方法:


+(void)log {
[self.class logName];
// [self logName]; 他们是一个意思
}


这样当我们需要从一个类的实例对象来获取isa链,那么我们不应该通过这个类方法来获取。



NSObject *objc = [NSObject new];
[objc class]; // class
[[objc class] class]; // meta class
[[[objc class] class] class]; // root meta class

你的本意是上面的意思,但是这个错误的其实这段代码的含义是这样的:


NSObject *objc = [NSObject new];
[objc class]; // class
[[objc class] class]; // class
[[[objc class] class] class]; // class


因为类方法+(Class)class返回的是self



-(Class)class
实例方法,源码是:
- (Class)class { return object_getClass(self); }
我们从这个实例方法中我们可以看出来其实调用的是object_getClass(id)那么这个方法的源码是什么呢?请看下一个章节


object_getClass

源码:


Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}

至于obj_getIsa()这个方法是其实是获取就是获取Class结构体中isa所指向的class指针。你可以通过看源码来了解obj_getIsa()的具体实现,源码



我们可以通过Class object_getClass(id obj)来获取isa链条



NSObject *objc = [NSObject new];
object_getClass(objc); // class
object_getClass(object_getClass(objc)); // meta class
object_getClass(object_getClass(object_getClass(objc))); //root meta class

我的问题

其实前面的知识,只是我通过看别的博客和简书得知,这里也就是做个记录,现在我要记录一下我疑惑的地方,并且通过做了验证的:


{
Class personClass = [Person class];
NSLog(@"Class------%p", personClass);
[self logPropertyAndIvarWithClass:personClass];

Person *person = [Person new];
Class class = person.class;
NSLog(@"Object------%p", class);
[self logPropertyAndIvarWithClass:class];
// 通过实例方法的-(Class)class 和类方法+(Class)class他们指向都是同一个指针,我们知道类在程序中也是一个对象,他们是一个单利。
}
- (void)logPropertyAndIvarWithClass:(Class)class {
unsigned int ivarCount = 0;
Ivar *ivars = class_copyIvarList(class, &ivarCount);
for (int i = 0 ; i < ivarCount; i++) {
Ivar ivar = ivars[i];
NSLog(@"ivar -- %@", [NSString stringWithUTF8String:ivar_getName(ivar)]);
}

unsigned int propertyCount = 0;
objc_property_t *properties = class_copyPropertyList(class, &propertyCount);
for (int i = 0 ; i < propertyCount; i++) {
objc_property_t property = properties[i];
NSLog(@"property -- %@", [NSString stringWithUTF8String:property_getName(property)]);
}
}
// 通过上面的两个方法中,我知道ivar 要比property的数量多。


注意:根据runtime获取出来的property,只能是自己本类的property,而不能打印出 继承父类 的property









最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台