Runtime定义:
是一套汇编,C,C++组成的一套API,给OC提供运行时特性。
运行时
将代码,系统库等装载到内存
编译时
将我们写的高级语言翻译成二进制语言
OC对象的本质:结构体(继承于结构体)
OC方法的本质:发送消息
消息的组成:
((void (*)(id, SEL))(void *)objc_msgSend)((id)p, sel_registerName("run"));
// void *)objc_msgSend)((id)p 消息接受者
// sel_registerName("run") 方法编号 --- name
- 对象方法存在类中
- 类方法存在元类中
- 对象方法和类方法在其对象中都是以实例方法存在
runtime底层代码分析
objc_msgSend消息寻找方法实现
会首先从cache_t 中寻找;如果没有找到,会有一个慢速的,通过C方法寻找;否则,就是一个复杂的过程,找到方法实现并且存储进cache_t中。
runtime底层中为什么要使用汇编?
- 快。我们知道C还会进行编译成汇编,所以汇编是更快的;
- 但是真正更为重要的原因是,用C实现不了。因为C是无法保留指针,然后随时跳转到任意的指针。我们写C方法的时候,是一定要知道函数地址的,否则编译不通过就是这个原因。于是使用汇编,将一个指针保留,等待需要的时候才指定想要的地址。汇编通过寄存器达到想要的实现。
汇编部分
C/C++部分
动态方法解析
消息转发
应用
动态创建类,并且添加属性和方法
Class superClass = [UIViewController class];
cls = objc_allocateClassPair(superClass, clsName, 0);
class_addIvar(cls, "ending", sizeof(NSString *), log2(sizeof(NSString *)), @encode(NSString *));
class_addIvar(cls, "show_lb", sizeof(UILabel *), log2(sizeof(UILabel *)), @encode(UILabel *));
objc_registerClassPair(cls);
Method method = class_getInstanceMethod([self class], @selector(lg_instancemethod));
IMP methodIMP = method_getImplementation(method);
const char *types = method_getTypeEncoding(method);
BOOL rest = class_addMethod(cls, @selector(viewDidLoad), methodIMP, types);