void test(int a)
{
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
[super forwardInvocation:anInvocation];
int a = 10;
test(a);
}
查看super的底层调用什么
我们转成c++看到是调用的objc_msgSend2方法
((void (*)(__rw_objc_super *, SEL, NSInvocation *))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Person"))}, sel_registerName("forwardInvocation:"), (NSInvocation *)anInvocation);
//简化成
objc_msgSendSuper{(id)self, (id)class_getSuperclass(objc_getClass("Person"))}, sel_registerName("forwardInvocation:"), (NSInvocation *)anInvocation);
通过汇编代码查看的是
打断点,然后进入debug->Debug Workflow->Always Show Disassembly
0x100000e49 <+73>: callq 0x100000ef4 ; symbol stub for: objc_msgSendSuper2
objc_msgSendSuper2(struct,@selector(sss),invocation)
Product->perform Action ->assemble "文件"
现在LLVM编译器
会想讲OC->中间代码(.ll文件)->汇编->机器代码
可以使用以下命令行指令生成中间代码
clang -emit-llvm -S main.m
因为这个中间代码是支持不同平台的,他转成汇编的时候,会根据不同的平台(不同平台的cpu架构不一样),生成不同汇编代码,所以我们生成中间的代码的时候不用指定平台,
我们平时转成的cpp文件只能用来参考,因为C++语法跟OC比较像,大家比较容易读懂,大部分代码都是可以转成C++代码来看他的底层实现的
语法简介
@ - 全局变量
% - 局部变量
alloca - 在当前执行的函数的堆栈帧中分配内存,当该函数返回到其调用者时,将自动释放内存
i32 - 32位4字节的整数
align - 对齐
load - 读出,store 写入
icmp - 两个整数值比较,返回布尔值
br - 选择分支,根据条件来转向label,不根据条件跳转的话类似 goto
label - 代码标签
call - 调用函数
具体可以参考官方文档:https://llvm.org/docs/LangRef.html
网友评论