iOS内功篇:runtime

Ios-OC phil 5年前 (2016-03-27) 1604次浏览 0个评论

文/明仔Su(简书作者)
原文链接:http://www.jianshu.com/p/f493bc6a949e/comments/1688988#comment-1688988
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

前言

本来打算写一篇关于runtime的学习总结,无奈长篇大论不是我的风格,就像写申论一样痛苦,加之网上关于tuntime的文章多如牛毛,应该也够童子们学习的了,今天就随便聊聊我的理解吧。

runtime是什么

对于初学者,runtime如尼斯湖水怪一样,只存在于传说中,对于开发者,runtime是做好iOS开发,或是深刻掌握Objective C所必需理解的东西。大公司面试都喜欢问:你对runtime熟悉吗?并不是runtime在开发中经常用到,我认为它是OC最核心的部分,只有掌握好它,你才能理解其底层的原理,而不是做一个只会造轮子的码农。要练成盖世神功,需先奠定自身深厚的内功,而tuntime就是iOS开发中的内功。

那么runtime到底是什么鬼?

听起来蛮抽象的,我们来点通俗的吧?没问题~~
我们先写一句OC的代码

那么在运行时runtime会将它转化成C语言的代码

这个方法就是发送消息的方法,类似这样的方法runtime提供了很多,比如:

那么我们可以利用这些方法干点什么?

以上就是runtime的通俗解释,只是稍微举个例子,更多用法大家可以发挥聪明才智,举一反三。

方法调用流程

通俗地讲,调用方法(包含实例方法和类方法)相当于給一个对象发送消息。

下面以实例对象调用方法[blackDog walk]为例描述方法调用的流程:

第一种情况编译器会报错,第二种需要到运行时才能确定对象能否接收指定的消息,这时候会进入消息转发的流程:

消息转发流程

1、动态方法解析
接收到未知消息时(假设blackDog的walk方法尚未实现),runtime会调用+resolveInstanceMethod:(实例方法)或者+resolveClassMethod:(类方法)
在该方法中,我们可以給未知消息新增一个已经实现了的方法。

2、备用接收者
如果以上方法没有做处理,runtime会调用- (id)forwardingTargetForSelector:(SEL)aSelector方法。
如果该方法返回了一个非nil(也不能是self)的对象,而且该对象实现了这个方法,那么这个对象就成了消息的接收者,消息就被分发到该对象。
适用情况:通常在对象内部使用,让内部的另外一个对象处理消息,在外面看起来就像是该对象处理了消息。
比如:blackDog让女朋友whiteDog来接收这个消息

3、完整消息转发
- (void)forwardInvocation:(NSInvocation *)anInvocation方法中选择转发消息的对象,其中anInvocation对象封装了未知消息的所有细节,并保留调用结果发送到原始调用者。
比如:blackDog将消息完整转发給主人dogOwner来处理

4、如果在以上三个方法都没有处理未知消息,则会引发异常。

后记

本文主要通俗地描述了runtime的概念,并对其主要作用做了简单的概括,旨在給读者抛砖引玉,runtime的奥妙之处就由读者多多探索学习了。
初学者需要更深入地学习:
1、基本概念:Class、Ivar、Method等等
2、消息转发机制
3、在<objc/runtime.h>中理解runtime提供的方法和功能
4、在实际开发中如何灵活运用runtime

传送门:
iOS runtime实战应用:成员变量和属性
iOS runtime实战应用:关联对象
iOS runtime实战应用:Method Swizzling


版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明iOS内功篇:runtime
喜欢 (0)