iOS-Runtime 详解
Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的。比如:
Objective-C的方法调用实则为“发送消息”,我们来看[dog eat]实际会被编译器转化为
若方法中函数参数,则为:
如果消息的接收者能够找到对应的方法,那么就相当于直接执行了接收者这个对象的特
定方法; 否则,消息要么被转发,或是临时向接收者动态添加这个方法对应的实现内
容,要么就干脆就crash掉。
现在可以看出[d pg eat ]真的不是一个简简单单的方法调用。因为这只是在编译阶段确定
了要向接收者发送eat 这条消息,而d g将要如何响应这条消息,那就要看运行时发生的
情况来决定了。
Objective-C 的Runtime 铸就了它动态语言的特性,这些深层次的知识虽然平时写代码用
的少一些,但是却是每个Objc 程序员需要了解的。
Runtime其实有两个版本"modern”和“legacy"。我们现在用的Objective-C 2 .0 采用的是
现行(Modern)版的Runtime系统,只能运行在iOS 和OS X 10 5 之后的64位程序中。而
OS X较老的32位程序仍采用Objective-C 1中的(早期)Legacy 版本的Runtime 系统。
这两个版本最大的区别在于当你更改一个类的实例变量的布局时,在早期版本中你需要
重新编译它的子类,而现行版就不需要。
Runtime基本是用C和汇编写的,可见苹果为了动态系统的高效而作出的努力。你可以在
这里下到苹果维护的开源代码。苹果和GNU各自维护一个开源的runtime版本,这两个版
本之间都在努力的保持一致。
weak 实现原理的概括
Runtime维护了一个weak表,用于存储指向某
个对象的所有weak指针。weak表其实是一个
hash (哈希) 表,Key是所指对象的地址,
Value是weak指针的地址(这个地址的值是所
指对象指针的地址) 数组。
weak 的实现原理可以概括一下三步:
1、初始化时: runtime会调用objc_initWeak
函数,初始化一个新的weak指针指向对象的
地址。
2、添加引用时: objc_initWeak函数会调用
objc_storeWeak()
obj c_storeWeak() 区数,
的作用是更新指针指向,创建对应的弱引用
表。
3、释放时,调用clearDeallocating函数。
clearDeallocating函数首先根据对象地址获取
所有weak指针地址的数组,然后遍历这个数
组把其中的数据设为nil,最后把这个entry从
weak表中删除,最后清理对象的记录。
下面将开始详细介绍每一步:
1、初始化时: runtime会调用
objc_initWeak函数,
objc_initWeak函数会初始化一
个新的weak指针指向对象的地址。
示例代码:
NSObject *obj= [NSObject lloc] init];
id _weak obj1= obj;
Runtime 的作用:
Objc 在三种层面上与 Runtime 系统进行交互:
1.通过 Objective-C 源代码
2.通过 Foundation 框架的 NSObject 类定义的方法
3.通过对 Runtime 库函数的直接调用
验证OC底层实现:
第一步:创建命令行项目
第二步:创建一个Person类
第三步:打开main.m函数,将Person添加到里面
第四步:进入终端,进入该目录下,将mian.m转成C语言文件
clang -rewrite-objc的作用是把oc代码转写成c/c++代码
执行之后,目录下多出一个main.cpp文件
第五步:打开main.cpp到最后,进行OC代码与C语言代码的比较
Runtime项目中的实用:
案例:因为NSURL出现汉字后,url为空,但是又不会报错
解决方案一:使用Category换一个
然后调用新的方法,新方法内部加上判断
解决方案二:利用runtime动态进行函数实现交换
第一步:为什么使用runtime??
优点:不需要进行太大的修改,而且继续使用原生方法名,只不过方法实现改变了!
弊端:要进行及时的注释,不然很容易忘记,出错
第二步:原理
runtime:可以交换方法的实现!!
第三步:代码实现
在Category刚刚加载的时候就需要对函数方法进行交换
1、导入头文件#import
2、在load函数中进行函数实现的交换
3、拿到这两个方法
class_getClassMethod 获取类方法
class_getInstanceMethod 获取对象方法
4、交换方法
今天给大家的分享就到这吧!有收获,或者喜欢小编的可以关注加小编的微信同时也欢迎大家加入或小编的iOS交流群687528266,点击链接加入群聊【iOS软件开发学习交流】:https://jq.qq.com/?_wv=1027&k=53OMouY,群里会提供相关面试资料,书籍欢迎大家入驻!大家一起交流成长!!