1
我们是通过[super somemethod]来调用父类方法的。在调用的父类方法中,self还是子类的对象。也可以通过objc_msgSendSuper这种方式来调用父类方法,传入一个struct objc_super 结构体参数。
objc_msgSendSuper2和objc_msgSendSuper
前者是私用的,只能由系统转化,即将[super somemethod]转化为objc_msgSendSuper2。后者是公开的,可以手动调用。
2
参数有所不同
手动调用[super method]时,系统生成的汇编代码中,rdi是一个地址,存放着receiver和Class,这个Class就是receiver的isa。即[receiver class]或object_getClass(receiver)。
0x7fff67bea280 <+0>: movq 0x8(%rdi), %r10
0x7fff67bea284 <+4>: movq (%rdi), %rdi
0x7fff67bea287 <+7>: movq 0x8(%r10), %r10
在_objc_msgSendSuper2内部中,1、是取出rdi+8处存放的内容,即receiver的isa。2、是取出rdi处存放的内容赋值给rdi,即receiver。3、再获取这个isa的superclass,然后进行方法查找。
手动调用_objc_msgSendSuper时,先构建struct objc_super 结构体参数
struct objc_super superclazz =
{
.receiver = receiver,
.super_class = class_getSuperclass(object_getClass(receiver))
};
void (*objc_msgSendSuperCasted)(void *, SEL, id) = (void *)objc_msgSendSuper;
objc_msgSendSuperCasted(&superclazz, @selector(somemethod), nil);
参数的super_class是receiver的isa的superclass,调用时将结构体参数的地址传过去的,这点objc_msgSendSuper2类似。
0x7fff67bea200 <+0>: movq 0x8(%rdi), %r10
0x7fff67bea204 <+4>: movq (%rdi), %rdi
在objc_msgSendSuper内部,1、取出rdi+8处存放的内容,2、是取出rdi处存放的内容赋值给rdi,即receiver,然后进行查找的。少了一个获取isa的superclass步骤,所以结构体中的super_class 要赋值为class_getSuperclass(object_getClass(receiver))。
3
objc_msgSend中是先获得receiver的isa,然后再进行查找的。