趣谈iOS运行时之方法调用原理

导语

一个成熟的计算机语言必然有丰富的体系,复杂的容错机制,处理逻辑以及判断逻辑。但这些复杂的逻辑都是围绕一个主线丰富和展开的,所以在学习计算机语言的时候,先掌握核心,然后了解其原理,明白程序语言设计的实质和当时选择这种处理方式的原因是极其必要的,而且也是学习语言的捷径。

所以在学习的过程中,需要把握几个核心
先专注主线,后丰富周边;
先宏观了解,后微观精通;
多设身处地思考,理解代码设计的原因;
理解代码设计的原理和优化


OC中处理方法的业务逻辑和其他语言不同,OC语言是动态语言(动态绑定动态加载(dynamatic binding),动态类型)。其中动态加载就涉及到OC的运行时。在OC中,方法是动态实现的,调用方法实际就是在发送消息
试想一下,一个方法的实现必然包含三个部分:

1.执行方法的对象
2.方法名称
3.不确定的参数

SEL只是一个方法名称IMP才是执行方法最终的函数,IMP包含这三个部分IMP 是一个函数指针,这个被指向的函数包含一个接收消息的 对象 id(self 指针), 调用方法的选标 SEL (方法名),以及不定个数的方法参数,并返回一个 id。也就是说 IMP 是消息最终调用的执行代码,是方法真正的实现代码 。


提问时间到了:

  • 动态和静态有什么区别?
  • 执行方法是怎么实现的?
  • OC的方法和C语言的函数原理一样么?

动态和静态有区别的;首先我们从最表层理解,一个方法的实现必然要包含执行者,方法名和不确定的参数和返回值。无论是静态或者动态方法都必须这三个必要元素(动态和静态的区别就在于在何时确定这些必要元素)。
方法的执行包含编译和运行两个过程。

  • 静态方法是在编译时已经确定了三个要素,且不能更改。若类型不对,就会直接发出警告。
  • 而OC的动态方法可以直接跳过编译,在运行时才开始添加函数调用,决定执行方法的三个要素。这就是动态方法(至于怎么执行,下面开始讲解)

这三个元素是如何确定的呢?首先我们看一段示例代码

Dog *aDog = [[Dog alloc]init];
[aDog run];

在执行方法时,是怎么确定的呢?
此时我们需要注意OC内部方法的实质:OC中,方法实现实质就是发送消息。
[aDog run];代码的实质就是[ objc_sendMsg],它会找到执行方法的三个要素,找到就按照规则执行。
发送消息是通过 objc_send(id, SEL, ...) 来实现的,它首先会在对象的类对象的 cachemethodlist 以及父类对象的 cache,methodlist 中依次查找 SEL 对应 的 IMP;
如果没有找到且实现了动态方法决议机制就会进行决议,

如果没有实现动态方法决议机制或决议失败且实现了消息转发机制就会进入消息转发流程,否则程序 crash。也就是说如果同时提供了动态方法决议消息转发,那么动态方法决议先于消息转发,只有当动态方法决议依然无法正确决议 selector 的 实现,才会尝试进行消息转发。当然,实际过程不可能那么简单,在开发语言之初,肯定会完善各种复杂场景和做了很多优化,接下来我们一起研究下OC对方法执行和扩展和优化:

  • 第一步:先找方法
  • 第二步:动态方法决议
  • 第三部:消息转发
  • 最后: 报错

消息转发

通常,给一个对象发送它不能处理的消息会得到出错提示,然而,Objective-C运行时系统在抛出错误之前, 会给消息接收对象发送一条特别的消息 forwardInvocation 来通该对象,该消息的唯一参数是个 NSInvocation 类型的对象——该对象封装了原始的消息和消息的参数。我们可以实现 forwardInvocation:方法来对不能处理的消息做一些默认的处理,也可以将消息转发给其他对 象来处理,而不抛出错误。

  • 1,首先去该类的方法cache中查找,如果找到了就返回它;
  • 2,如果没有找到,就去该类的方法列表中查找。如果在该类的方法列表中找到了,则将 IMP 返回,并将 它加入 cache 中缓存起来。根据最近使用原则,这个方法再次调用的可能性很大,缓存起来可以节省下次 调用再次查找的开销。
  • 3,如果在该类的方法列表中没找到对应的IMP,在通过该类结构中的super_class指针在其父类结构的方法列表中去查找,直到在某个父类的方法列表中找到对应的IMP,返回它,并加入cache中;
  • 4,如果在自身以及所有父类的方法列表中都没有找到对应的 IMP,则看是不是可以进行动态方法决议(后 面有专文讲述这个话题);
  • 5,如果动态方法决议没能解决问题,进入下面要讲的消息转发流程。便利函数:我们可以通过 NSObject 的一些方法获取运行时信息或动态执行一些消息:

class 返回对象的类;
isKindOfClass,isMemberOfClass 检查对象是否在指定的类继承体系中;
respondsToSelector 检查对象能否相应指定的消息;
conformsToProtocol 检查对象是否实现了指定协议类的方法;
methodForSelector 返回指定方法实现的地址;
performSelector:withObject 执行 SEL 所指代的方法

-
OC做为一门面向对象语言,自然具有面向对象的语言特性,如封装继承多态。他具有静态语言的特性(如C++),又有动态语言的效率(动态绑定、动态加载等)。整体来说,确实是一门不错的编程语言。


OC的动态语言特性

现在,让我来想想OC的动态语言特性。OC的动态特性表现为了三个方面:
动态类型动态绑定动态加载
之所以叫做动态,是因为必须到运行时(runtime)才会做一些事情。

(1)动态类型

动态类型,说简单点就是id类型。动态类型是跟静态类型相对的。像内置的明确的基本类型都属于静态类型(int、NSString等)。静态类型在编译的时候就能被识别出来。所以,若程序发生了类型不对应,编译器就会发出警告。而动态类型就编译器编译的时候是不能被识别的,要等到运行时(runtime),即程序运行的时候才会根据语境来识别。所以这里面就有两个概念要分清:编译时跟运行时。

(2)动态绑定

动态绑定(dynamic binding)貌似比较难记忆,但事实上很简单,只需记住关键词@selector/SEL即可。先来看看“函数”,对于其他一些静态语言,比如c++,一般在编译的时候就已经将将要调用的函数的函数签名都告诉编译器了。静态的,不能改变。而在OC中,其实是没有函数的概念的,我们叫“消息机制”,所谓的函数调用就是给对象发送一条消息。这时,动态绑定的特性就来了。OC可以先跳过编译,到运行的时候才动态地添加函数调用,在运行时才决定要调用什么方法,需要传什么参数进去。这就是动态绑定,要实现他就必须用SEL变量绑定一个方法。最终形成的这个SEL变量就代表一个方法的引用。这里要注意一点:SEL并不是C里面的函数指针,虽然很像,但真心不是函数指针。SEL变量只是一个整数,他是该方法的ID。以前的函数调用,是根据函数名,也就是字符串去查找函数体。但现在,我们是根据一个ID整数来查找方法,整数的查找字自然要比字符串的查找快得多!所以,动态绑定的特定不仅方便,而且效率更高。

(3)动态加载

动态加载就是根据需求动态地加载资源。我对动态加载比较陌生,所以就没什么可总结的啦。等以后慢慢完善。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 网络协议是计算机网络中进行数据传输和通信的规则和约定。PDF(Portable Document Format)是一种由Adobe开发的文件格式,用于以可靠的方式呈现和交换电子文档。 在谈论网络协议的PDF下载时,我们可以探讨以下趣闻: 首先,网络协议的PDF下载可以帮助我们更好地理解和学习网络协议。网络协议本身是一种抽象的概念,有时候很难通过文字或图片来完全理解。但是,通过以PDF格式提供的文档,我们可以更直观地看到网络协议的结构、流程和细节,使得学习变得更加容易和有趣。 其次,网络协议的PDF下载还能帮助我们及时了解和跟进最新的协议标准。网络协议是一门不断发展的学科,新的协议版本和标准经常被提出和更新。通过及时下载最新的协议文档,我们可以了解最新的协议规范和改进,从而更好地应用它们于实际网络环境中。 此外,网络协议的PDF下载也给了我们方便地和他人共享学习资源的机会。通过将网络协议的文档以PDF格式发布在互联网上,任何人都能够自由下载和阅读,促进了知识的传播和共享。在学术和研究领域,这种方式也为学者们提供了方便的途径来分享最新的网络协议研究成果。 总之,网络协议的PDF下载不仅能够促进我们更好地理解和学习网络协议,还能帮助我们及时了解最新的协议标准,并且方便地与他人共享学习资源。无论是对于专业人员还是对于普通用户,网络协议的PDF下载都具有重要的意义和趣味性。 ### 回答2: 网络协议是计算机网络中的基础,它定义了数据在网络中传输的规则和方式。网络协议可以确保数据的可靠传输,有效地管理网络资源,并实现各种网络应用功能。 趣谈网络协议是一本介绍网络协议的有趣读物,可以以轻松、幽默的方式解释复杂的网络协议概念和原理。这本书通常以PDF格式提供下载,方便读者在任何设备上阅读。 下载这本书的PDF版本,可以享受以下好处: 首先,PDF格式具有跨平台和跨设备的特点。不论您使用的是电脑、平板还是手机,只要安装了合适的PDF阅读器软件,就可以轻松打开并阅读这本书。 其次,下载PDF可以实现离线阅读。无论您身处何地,只要下载好了PDF文件,即便没有网络连接,也可以随时随地阅读网络协议的趣谈故事。 此外,PDF格式使得阅读更加方便。您可以在PDF阅读器中进行文字搜索、加注释、划重点,甚至可以调整字号的大小,以适应不同的阅读环境。 最后,通过下载PDF,您还可以将这本书保存到自己的电脑或移动设备上,以备日后参考。您可以在需要的时候,随时翻阅这本书,方便复习和查找相关内容。 总之,趣谈网络协议PDF的下载为我们提供了方便、快捷、随时随地的阅读体验。无论是想了解网络协议,还是希望在计算机网络领域深入学习,这本书都会是一本有趣而又实用的读物。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值