4.动态运行时(RunTime)
- 基础数据结构
- 对象、类对象、元类对象是怎么理解的?以及他们之间的关系是怎样的(实例与类对象之间的关系以及类对象与元类对象之间的关系)?
- OC语言中的消息传递机制是怎样的?
- 缓存查找 (我们进行方法查找的过程当中,如何进行缓存的方法查找?会使用到系统或者说Runtime中一个方法缓存的机制,这个机制又是怎样运行的呢?)
- 消息转发流程是怎样的?
- Method-Swizzling(方法混写)是Runtime的一种运用(我们可以再运行时,去替换一些方法的实现,也得益于动态运行时这一个特性),可能会结合实际的场景,比如说通过时长统计框架这样的考察来了解对于Runtime的Methood-Swizzling技术的一个实际的运用
- 动态添加方法(Runtime提供的功能实现)
- 动态方法解析(Runtime提供的功能实现)
Method-Swizzling
什么是Method-Swizzling?
假如类中有两个方法
一个是selector1,对应的方法实现是IMP1
一个是selector2,对应的方法实现是IMP2
经过Method-Swizzling操作
可以修改selector对应的实际的方法实现,当我们给这个对象发送selector1的时候,执行的是IMP2,发送selector2的时候,执行的是IMP1
Method Swizzling发生在运行时,主要是将两个Method交换,Method Swizzling可以写在任何地方,代码执行完毕互换才起作用
每个类都有一个方法列表(Dispatch Table),本质是将类中的SEL和IMP一一对应,Method Swizzling就是对Dispatch Table进行操作,让SEL对应别的IMP
OC的Runtime特性,当调用一个类对象的方法时,内部是给这个类对象发送消息,我们通过这个对象的Dispatch Table ,在这里找出对应的SEL,而SEL对应着IMP,我们通过IMP则找到了方法的实现
#import "RuntimeObject.h"
#import <objc/runtime.h>
@implementation RuntimeObject
+ (void)load
{
//获取test方法 其实是根据当前对象的class_getInstanceMethod来获取结构体Method
Method test = class_getInstanceMethod(self, @selector(test));
//获取otherTest方法
Method otherTest = class_getInstanceMethod(self, @selector(otherTest));
//交换
method_exchangeImplementations(test, otherTest);
}
- (void)test{
NSLog(@"test");
}
- (void)otherTest{
/*在系统层面会转换成objc_msgSend,然后通过这个选择器因子otherTest去找他的具体实现,
因为在load中已经做了两个方法的替换,实际上是调用了test的具体实现,所以不会产生死循环
*/
[self otherTest];
NSLog(@"otherTest");
}