runtime详解-初版
(一)runtime含义:运行时。是一套底层c语言的APT,我们的代码,是基于它来实现的。消息转发机制;
例如:执行一个方法[receiver message:(id)arg...];
底层运行是被编译器转化为objc_msgSend(receiver, selector, arg1, arg2, …);
(二)为什么需要runtime
1.oc 是一门动态语言,它会把一些工作放在代码运行时才处理而非编译时;如在运行时才确定很多类的成员变量,因此编译器是不够的,还需要一个运行时系统(runtime system)来处理编译后的代码;
2.runtime 基本使用c和汇编写的,为了动态系统的高效而努力;
(三)消息转发机制
1.动态方法解析;+ (BOOL)resolveInstanceMethod:(SEL)sel; 实现方法,指定是否动态添加方法。若返回NO,则进入下一步。若返回YES,则通过class_addMethod函数动态添加方法,消息的到处理,该流程完毕;
2.找备用;-(id)forwardingTargetForSelector:(SEL)aSelector; 这是运行时给目标SEL的第二次机会,用于指定那个对象响应这个SEL,不能指定为self,因为第一步中self已经找了。若返回nil,表示没有响应者,则会进入第三步。若返回某个对象,则会调用该对象的方法;
3.消息转发
(1)、重定向、方法签名;-(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector;通过这个方法指定方法签名,若返回nil,则表示不处理。若返回方法签名,则会进入下一步;
(2)、转发;-(void)forwardInvocation:(NSInvocation*)anInvocation;我们可以通过anInvocation对象做很多处理,比如修改实现方法,修改响应对象;
4.消息无法处理;-(void)doesNotRecognizeSelector:(SEL)aSelector;如果没有实现这个方法则会crash;
(四)runtime的实际开发中的用处;https://github.com/macios/runTime
1.利用消息转发模拟多继承;
2.消息拦截/交换;
3.拓展已有类的属性<伪属性>;
4.动态添加方法;
5.自定义timer解决循环引用 self>timer>self;
6.模拟kvo实现;
(五)常用函数
objc_setAssociatedObject设置关联对象;
objc_getAssociatedObject获取关联对象;
class_getInstanceMethod得到类的实例方法;
class_getClassMethod得到类的类方法;
method_exchangeImplementations;方法交换;
Ivar*ivarList = class_copyIvarList([selfclass], &count);//runtime获取所有实例变量
Method*methodList = class_copyMethodList([cla class], &count);//获取所有方法
class_addMethod;填加方法