iOS runTime运行时机制

         RunTime简称运行时.OC就是运行时机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候就会决定调用哪个函数. 而对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数. 只有在真正运行的时候才能根据函数的名称找到对应的函数来调用.

         OC-RunTime是个运行时的库,又C和汇编实现.通过RunTime封装的C结构体和函数可以在程序运行时,创建、检查、、修改类的对象及其方法. 甚至可以替换和交换方法的实现

参考:iOS Runtime原理及使用 -

函数的定义

对对象进行操作的方法一般以object_开头

对类进行操作的方法一般以class_开头

对类或对象的方法进行操作的方法一般以method_开头

对成员变量进行操作的方法一般以ivar_开头

对属性进行操作的方法一般以property_开头开头

对协议进行操作的方法一般以protocol_开头

根据以上的函数的前缀 可以大致了解到层级关系。

对于以objc_开头的方法,则是runtime最终的管家,可以获取内存中类的加载信息,类的列表,关联对象和关联属性等操作。

runtime应用


         1 发送消息

            objc_msgSend


         2 交换方法

         class_replaceMethod    替换类方法的定义(替换一个不存在的方法时,会调用class_addMethod为该类增加新方法)

         exchangeImplementations    交换方法

         setImplemention            设置方法


         3 类/对象的关联对象(动态关联属性)

         为类添加一个相关的对象,通常用语存储类信息. 例如存储类的属性列表数组, 为讲来字典转型模型的方便


         对象在内存中的排布可以看成一个结构体, 该结构体的大小并不能动态变化, 所以无法在运行时动态给对象增加成员变量. 相对的, 对象的方法定义都保存在类的可变区域中.

         根据class的描述信息,其中methodList可访问类中定义的方法的指针, 通过修改该指针所指向的指针的值,我们可以实现为类动态增加方法实现

         因此,我们可以实现动态为一个类增加成员方法,但是不能直接为类增加成员变量, 这就是category的实现原理


         4 动态添加方法

         开发使用场景: 如果一个类方法非常多, 加载到内存的时候比较耗费资源, 需要给每个方法生成映射表, 可以使用动态给某个类, 添加方法解决

         经典面试题: 有没有使用performSelector,其实主要想问你有没有动态添加过方法


         5 字典转模型KVC实现

         通过Class的结构体内容,可以看到ivars指针指向包含了个种成员变量的结构体, 通过它可以得到勒种定义的成员变量, OC中提供了API方法:

         class_copyIvarList


         KVC: 把字典中所有值给模型的属性赋值. 要求字典中的key,必须要在模型里能找到相应的值,找不到就会报错

         通过重写KVC中forUndefinKKey这个方法,就不会进行报错 -setValue:forUndefineKey:


         另外,可以通过runtime的方法去x实现:把KVC的原理倒过来, 通过遍历模型model的值, 从字典中取值.

         原理: 用runtime提供的函数遍历Model自身所在属性, 如果属性在json中有对应的值, 则将其赋值

         核心方法: 在NSObject的分类中添加方法, 遍历: class_copyIvarList()


         6 消息转发


使用:

1  给button添加block回调方法, image添加图片判断方法

2 动态添加方法,perform Selector , 添加私有方法,比如,不实用schme的APP跳转,根据bundleID; 规避审核,IDFA的获取

3 把对象的实例变量 生成字典, 并且填充数据

你可能感兴趣的:(iOS runTime运行时机制)