教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Runtime 中的消息机制

Runtime 中的消息机制

发布时间:2021-12-19   编辑:jiaochengji.com
教程集为您提供Runtime 中的消息机制等资源,欢迎您收藏本站,我们将为您提供最新的Runtime 中的消息机制资源

说道Objective-C里面的消息机制,大部分人都知道是调用方法其实就是发送消息,一个叫objc_msgSend的东西负责的。今天结合《编写高质量iOS与OS X代码的52个有效方法》趴一趴消息机制。

<h4>为什么Objective-C里会有消息机制</h4>

这就是语言的基因问题了Smalltalk,之前在一本叫《代码的未来》了解到Smalltalk是一门比较古老的语言,在 Smalltalk 中一切皆对象,一切调用都是发消息。在它之前有Lisp 和 FORTRAN、COBOL并称为“古代编程语言三巨头”。

Objective-C是在C的基础上,借鉴 Smalltalk 的面向对象与消息机制扩展出来的语言,就像Golang语言天生自带并发基因。

<h4>发送消息的过程</h4>

在Objective-C中,如果向某个对象传递消息,那就会在运行时使用动态绑定(dynamic binding)机制来决定需要调用的方法。但是到了底层具体实现,却是普通的C语言函数实现的。这个实现的函数就是objc_msgSend,该函数定义如下:

<pre><code class="lang-go hljs">void objc_msgSend(id self, SEL cmd, ...) </code></code></pre>

这是一个参数个数可变的函数,第一参数代表接收者,第二个参数代表选择子(OC函数名),后续的参数就是消息(OC函数调用)中的那些参数

举例来说:

<pre><code class="lang-go hljs">id return = [git commit:parameter]; </code></code></pre>

上面的Objective-C方法在运行时会转换成如下函数:

<pre><code class="lang-go hljs">id return = objc_msgSend(git, @selector(commit), parameter); </code></code></pre>

objc_msgSend函数会在接收者所属的类中搜寻其方法列表,如果能找到这个跟选择子名称相同的方法,就跳转到其实现代码,往下执行。若是当前类没找到,那就沿着继承体系继续向上查找,等找到合适方法之后再跳转 ,如果最终还是找不到,那就进入消息转发的流程去进行处理了。

<ol><li>

说过了OC的函数调用实现,你会觉得消息转发要处理很多,尤其是在搜索上,幸运的是objc_msgSend在搜索这块是有做缓存的,每个OC的类都有一块这样的缓存,objc_msgSend会将匹配结果缓存在快速映射表(fast map)中,这样以来这个类一些频繁调用的方法会出现在fast map 中,不用再去一遍一遍的在方法列表中搜索了。

</li> <li>

还有一个有趣的点,就是在底层处理发送消息的时候,有用到尾调用优化,大概原理就是在函数末尾调用某个不含返回值函数时,编译器会自动的不在栈空间上重新进行分配内存,而是直接释放所有调用函数内部的局部变量,然后直接进入被调用函数的地址。

</li> </ol><h4>写在最后</h4>

《编写高质量iOS与OS X代码的52个有效方法》是一本很不错的书,想在OC做的深的一点话,最好看看这本书,必会有不少收益


到此这篇关于“Runtime 中的消息机制”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
处理ASP请求的内部讨论
Runtime 中的消息机制
golang 的runtime机制
VBS脚本运行库手册(1)-磁盘操作
Goroutine的调度分析(一)
golang runtime 简析
PHP实现页面后退的两种方法
C#中使用SendMessage
php 页面回退的两种实现方法
php表单提交后再后退 内容则默认清空的解决方法

[关闭]
~ ~