iOS Objective-C 消息机制原理

//联系人:石虎  QQ: 1224614774昵称:嗡嘛呢叭咪哄


一、OC 消息机制原理

/**

注意点: 1.在 OC 中,message与方法是在执行阶段绑定的,而不是编译阶段

       2.可以说 [a func] 这样一个调用,在编译阶段,编译器并不知道 func 要执行哪段代码。

      3.[a func]会被转换为 objc_msgSend(a, "someFunc"),字面的意思也很容易理解,就是给a这个instance,发“someFunc”这个消息,以selector的形式。在运行阶段,执行到上述的objc_msgSend这个函数时。

             4.函数内部会到 对应的内存地址,寻找 func 这个方法的地址,并执行。

            5.如果找不到,就会抛一个“unknown selector sent to instance”的异常

            注意:(比如.h中声明了方法,但.m中没有实现,就可以重现这个错误) 所以严格意义上来讲,任何Objective C的函数调用,编译阶段的表现,都只能算一种发消息的行为。


*/

      

二、为什么使用汇编语言    

    其实在 objc-msg-x86_64.s中包含了多个版本的 objc_msgSend方法,它们是根据返回值的类型和调用者的类型分别处理的:


objc_msgSendSuper:向父类发消息,返回值类型为id

objc_msgSend_fpret:返回值类型为 floating-point,其中包含 objc_msgSend_fp2ret入口处理返回值类型为longdouble的情况

objc_msgSend_stret:返回值为结构体

objc_msgSendSuper_stret:向父类发消息,返回值类型为结构体

    当需要发送消息时,编译器会生成中间代码,根据情况分别调用 objc_msgSend, objc_msgSend_stret, objc_msgSendSuper, objc_msgSendSuper_stret其中之一。



   这也是为什么 objc_msgSend要用汇编语言而不是 OCC C++语言来实现,因为单独一个方法定义满足不了多种类型返回值,有的方法返回id,有的返回int。考虑到不同类型参数返回值排列组合映射不同方法签名(method signature)的问题,那switch语句得老长了。

       这些原因可以总结为 Calling Convention,也就是说函数调用者与被调用者必须约定好参数与返回值在不同架构处理器上的存取规则,比如参数是以何种顺序存储在栈上,或是存储在哪些寄存器上。

除此之外还有其他原因,比如其可变参数用汇编处理起来最方便,因为找到IMP地址后参数都在栈上。

      要是用 C++传递可变参数那就悲剧了,prologue机制会弄乱地址(比如 i386上为了存储 ebp向后移位4byte),最后还要用 epilogue打扫战场。而且汇编程序执行效率高,在 Objective-C Runtime中调用频率较高的函数好多都用汇编写的。



谢谢!!!


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值