Demo
从经典的一个demo开始 。前提:XXSon继承自 XXFather。
@implementation XXSon
- (id)init
{
self = [super init];
if (self)
{
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));
}
return self;
}
@end
打印结果都是 XXSon。
分析
准备工作
- 我们知道向对象发送消息最终会转化成objc_msgSend方法,定义如下:
objc_msgSend(void /* id self, SEL op, ... */ )
第一个参数是接收消息的对象
第二个参数是方法选择器
-
super关键字接受消息时,会转化成objc_msgSendSuper方法,定义如下
objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
第一个参数是objc_super结构体
第二个参数是方法选择器
objc_super结构体的定义在 message.h文件中, 现在都是OBJC2,简化后定义如下:
/// Specifies the superclass of an instance.
struct objc_super {
/// Specifies an instance of a class.
__unsafe_unretained _Nonnull id receiver;
__unsafe_unretained _Nonnull Class super_class;
/* super_class is the first class to search */
};
super关键字表示让直接从super_class中开始查找方法的实现。
- Demo中的XXSon.m经过
clang -rewrite-objc XXSon.m编译后的.cpp文件之后的相关代码是:
static id _I_XXSon_init(XXSon * self, SEL _cmd) {
self = ((XXSon *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("XXSon"))}, sel_registerName("init"));
if (self)
{
NSLog((NSString *)&__NSConstantStringImpl__var_folders_4c_2bxyjsn12ggc69ffj64bxvbc0000gn_T_XXSon_089961_mi_0, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class"))));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_4c_2bxyjsn12ggc69ffj64bxvbc0000gn_T_XXSon_089961_mi_1, NSStringFromClass(((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("XXSon"))}, sel_registerName("class"))));
}
return self;
}
结果分析
- 调用
[self class]会转换成objc_msgSend(self, @selector(class))其receiver为self。调用class方法,因XXSon并未定义class方法,所以会从其父类XXFather中查找,XXFather中也未定义,会再从其父类NSObject中查找。NSObject中的class方法会调用object_getClass(),object_getClass()的定义在objc-class.mm文件中,具体如下:
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
[self class]的receiver为self,所以object_getClass这里的参数obj就是self。直接返回self的isa即 XXSon。
- 调用
[super class],会转化成objc_msgSendSuper, 同时会自动生成struct objc_super *super。objc_super->receiver为self(从.cpp文件中就可以看出来),objc_super-> super_class为XXFather。所以直接从XXFather中查找class方法,在NSObject中找到class方法。最后调用objc_msgSend(objc_super->receiver, @selector(class)), 此时object_getClass()方法的receiver为objc_super->receiver(即self)。 所以和[self class]的打印一样。












网友评论