RunTime-动态运行时

2019-10-14  本文已影响0人  Amor瑾年v

RunTime简介:

RunTime简称运行时。OC就是运行时机制,也就是运行时候的一些机制,其中最主要的就是消息机制。
对于C语言,函数的调用在编译的时候就会决定调用哪个函数,如果调用未实现的函数就会报错。对于OC语言,他是一门动态的语言,因为他在编译的时候并不能决定真正调用的是哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数进行调用。在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要声明过就不会报错。

RunTime消息机制

消息机制是运行时里面最重要的机制,OC中任何方法的调用,本质都是发送消息。

@selector(SEL):

这是一个方法选择器。主要作用是快速的通过方法名字查找到对应方法的函数指针,然后调用其函数也就是IMP。SEL其本身是一个Int类型的地址,地址中存放着方法名字。对于一个类中,每一个方法对应着一个SEL。所以一个类中不能存在两个名称相同的方法,即使参数类型不同也不行,因为SEL是根据方法名字生成的,相同的方法名称只能对应一个SEl。

实例方法和类方法的调用过程

屏幕快照 2019-10-14 上午10.07.40.png

实例方法的调用过程:首先会根据实例对象的isa指针找到他的类对象,在类对象的对象方法列表中去查找是否有对应实现,如果有就调用,没有就依次去类对象的父类中查找,一直找到NSObject还没有的话会进入消息转发,如果在消息转发流程(其中有三个方法)还是没有做处理,就会报找不到方法异常。

[图片上传中...(屏幕快照 2019-10-14 上午10.04.48.png-68eabe-1571018691218-0)]

类方法的调用过程:首先也是会根据类对象的isa指针找到它的元类,元类中存储着类方法列表,如果当前元类的类方法列表没有,再依次去元类的父类中查找对应实现,一直找到根元类,还是没有的话,这个时候与实例方法调用不同的是,如果类对象里面有同名的实例方法,就回去调用同名的实例方法。如果没有在进入消息转发,消息转发没做处理的话就会报找不到方法异常。

屏幕快照 2019-10-14 上午10.05.27.png

RunLoop的应用:

1.获取列表(比如获取类的属性列表,方法列表,成员变量列表)。比如实际开发中做归档解档的时候对象的属性很多的时候就可以用RunTime这个特性很方便的简化代码。
2.方法调用:正如上面所讲的实例方法调用和类方法调用。
3.拦截调用:拦截调用就是,在找不到调用的方法程序奔溃之前,你有机会通过重写NSObject的四个方法来处理。
4.动态添加方法:如果一个类方法非常多,其中可能许多方法暂时用不到。而加载类方法到内存的时候需要给每个方法生成映射表,比较耗费资源,这个时候就可以用Runtime动态添加方法。动态给某个类添加方法,相当于懒加载机制,类中许多方法暂时用不到,那么就先不加载,等用的时候再去加载。另外如果找不到对应的方法时就会来到拦截调用,也就是因为找不到方法实现,在奔溃之前可以调用的方法。当调用了没有实现的对象方法时,就会调用+(BOOL)resolveInstanceMethod:(SEL)sel方法当调用了没有实现的类方法时,就会调用+(BOOL)resolveClassMethod:(SEL)sel方法,我们就可以实现这两个方法动态的给实例方法或者类方法添加方法和方法实现。
5.方法交换:当系统自带的方法功能不够,需要给系统自带的方法扩展一些功能,并且保持原有的功能时,可以使用Runtime交换方法实现。这个特性可以用来处理开发中常见的奔溃(比如字典添加nil值,和数组越界等导致的奔溃)或者是统一添加埋点,可以很方便的解决这些问题。

上一篇下一篇

猜你喜欢

热点阅读