Runtime是什么?
runtime是OC底层的一套C语言的API(引入 <objc/runtime.h> 或<objc/message.h>),编译器最终都会将OC代码转化为运行时代码,底层是通过runtime创建的对象.
另外利用runtime 可以做一些OC不容易实现的功能
.动态交换两个方法的实现(特别是交换系统自带的方法)
.动态添加对象的成员变量和成员方法
.获得某个类的所有成员方法、所有成员变量
如何应用运行时?
1.将某些OC代码转为运行时代码,探究底层,比如block的实现原理(上边已讲到);
2.拦截系统自带的方法调用(Swizzle 黑魔法),比如拦截imageNamed:、viewDidLoad、alloc;
3.实现分类也可以增加属性;
4.实现NSCoding的自动归档和自动解档;
5.实现字典和模型的自动转换。
获得某个类的类方法 Method class_getClassMethod(Class cls , SEL name) 获得某个类的实例对象方法 Method class_getInstanceMethod(Class cls , SEL name) 交换两个方法的实现 void method_exchangeImplementations(Method m1 , Method m2)
#import "Car.h" @implementation Car - (void)run{ NSLog(@"********run********"); } - (void)play{ NSLog(@"********play********"); } + (void)run1{ NSLog(@"********run1********"); } + (void)play1{ NSLog(@"********play1********"); } @end
// 交换类方法 Method run1 = class_getClassMethod([Car class], @selector(run1)); Method play1 = class_getClassMethod([Car class], @selector(play1)); method_exchangeImplementations(play1, run1); [Car run1]; [Car play1]; Car *car = [[Car alloc] init]; [car run]; [car play]; // 交换对象方法 Method run = class_getInstanceMethod([Car class], @selector(run)); Method play = class_getInstanceMethod([Car class], @selector(play)); method_exchangeImplementations(play, run); [car run]; [car play]; Car *car2 = [[Car alloc] init]; [car2 run]; [car2 play]; [Car run1]; [Car play1]; 2017-09-09 16:26:07.773 Runtime[8352:190453] ********play1******** 2017-09-09 16:26:07.773 Runtime[8352:190453] ********run1******** 2017-09-09 16:26:07.773 Runtime[8352:190453] ********run******** 2017-09-09 16:26:07.773 Runtime[8352:190453] ********play******** 2017-09-09 16:26:07.773 Runtime[8352:190453] ********play******** 2017-09-09 16:26:07.774 Runtime[8352:190453] ********run******** 2017-09-09 16:26:07.774 Runtime[8352:190453] ********play******** 2017-09-09 16:26:07.774 Runtime[8352:190453] ********run******** 2017-09-09 16:26:07.774 Runtime[8352:190453] ********play1******** 2017-09-09 16:26:07.774 Runtime[8352:190453] ********run1********