super
作用
当我们创建好一个默认的controller,Xcode帮我们自动生成一些默认代码,其中就有super
:
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
@end
复制代码
我们都知道[super viewDidLoad]
是为了调用父类方法,以此为基础调用子类的一些方法,来实现功能需求.
super
本质
在了解本质之前,我一直理解的super就是代表父类,可能底层实现就是class_getSuperclass()
函数,然后配合msgSend
函数调用.
然而,事实不是如此.
我们先将上述代码转换为C/C++代码:
static void _I_ViewController_viewDidLoad(ViewController * self, SEL _cmd) {
((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self,
(id)class_getSuperclass(objc_getClass("ViewController"))
}, sel_registerName("viewDidLoad"));
}
复制代码
将强制转换等优化一下:
objc_msgSendSuper(
{ (id)self,
(id)class_getSuperclass(objc_getClass("ViewController"))
},
sel_registerName("viewDidLoad"));
复制代码
很明显,super的调用和我们预想的不太一样,调用函数是objc_msgSendSuper
,第一个参数是结构体包含了self
和superClass
,第二个参数是SEL
虽然转换的是objc_msgSendSuper
,但是我们断点显示的是objc_msgSendSuper2
方法,也就是说实际底层调用的是带数字2的函数,我们查找objc源码 :
断点:
源码解读并添加注释:
/********************************************************************
* id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
*
* struct objc_super {
* id receiver; // 消息接收者.[self]
* Class cls; // SUBCLASS of the class to search .[当前类]
* }
********************************************************************/
ENTRY _objc_msgSendSuper2
ldr r9, [r0, #CLASS] // class = struct super->class,取出传入的cls
ldr r9, [r9, #SUPERCLASS] // class = class->superclass,取出cls的父类
CacheLookup NORMAL, _objc_msgSendSuper2 // 从cls的父类中开始查找方法,先从缓存中查找,找到就调用,真正的调用者是传入的结构体的第一个成员`self`.
// cache hit, IMP in r12, eq already set for nonstret forwarding
ldr r0, [r0, #RECEIVER] // load real receiver
bx r12 // call imp
// 如果没有在缓存中找到,就去方法列表中查找,真正的调用者是传入的结构体的第一个成员`self`
CacheLookup2 NORMAL, _objc_msgSendSuper2
// cache miss
ldr r9, [r0, #CLASS] // class = struct super->class
ldr r9, [r9, #SUPERCLASS] // class = class->superclass
ldr r0, [r0, #RECEIVER] // load real receiver
b __objc_msgSend_uncached
END_ENTRY _objc_msgSendSuper2
复制代码
结论
-
super的调用,底层会转换为
_objc_msgSendSuper2
函数的调用,接收两个参数:
* id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
*
* struct objc_super {
* id receiver; // 消息接收者.[self]
* Class cls; // SUBCLASS of the class to search .[当前类]
* }
复制代码
-
receiver是消息接收者,cls决定了从哪里开始查找方法(cls->superClass)
-
通过编译转换的代码不一定是真正的执行代码,但实际八九不离十.
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END