基本概念
底层是一套纯c的语言,运行过程中会转换成runtie的c语言代码形式
运行时确定数据类型以及对应方法的绑定
oc需要runtime来创建类和消息发送和转发有什么作用
在程序运行中,动态的创建类,修改类的属性和方法(最常见的就是给catagory添加属性)
方法交换,获取对象的私有属性,字典转模型,kvc,归档,block
消息传递,转发
梧雨北辰a.png
3.消息转发:
当调用【类 方法】时,如[self act]
时
runtime会执行objc_msgSend(, ,)参数1:对象,参数2:方法编号,参数3:附带参数
之后查找这个这个类的IMP,先从cache里找,然后methodlist,supermethodlist,一直找到nsobjct类为止。如果还是找不到,runtime提供了三种方法来最后挽救:动态方法解析,消息接受者重定向,消息重定向
下面接着介绍这三种方法
1.动态方法解析
+(BOOL)resolveClassMethod:(SEL)sel{
if(sel == @selector(haveMeal:)){
class_addMethod(object_getClass(self), sel, class_getMethodImplementation(object_getClass(self), @selector(zs_haveMeal:)), "v@");
return YES; //添加函数实现,返回YES
}
return [class_getSuperclass(self) resolveClassMethod:sel];
}
2.消息接收者重定向
+ (id)forwardingTargetForSelector:(SEL)aSelector{
if (aSelector == @selector(takeExam:)) {
return [Student class];
}
return [super forwardingTargetForSelector:aSelector];
}
3.消息重定向
-(void)forwardInvocation:(NSInvocation *)anInvocation{
//1.从anInvocation中获取消息
SEL sel = anInvocation.selector;
//2.判断Student方法是否可以响应应sel
if ([self.student respondsToSelector:sel]) {
//2.1若可以响应,则将消息转发给其他对象处理
[anInvocation invokeWithTarget:self.student];
}else{
//2.2若仍然无法响应,则报错:找不到响应方法
[self doesNotRecognizeSelector:sel];
}
}
//需要从这个方法中获取的信息来创建NSInvocation对象,因此我们必须重写这个方法,为给定的selector提供一个合适的方法签名。
- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector{
NSMethodSignature *methodSignature = [super methodSignatureForSelector:aSelector];
if (!methodSignature) {
methodSignature = [NSMethodSignature signatureWithObjCTypes:"v@:*"];
}
return methodSignature;
}