runtime(三)应用 消息转发

OC 中方法调用是以消息传递实现的
[obj foo] 等同于 objc_msgSend(obj,@selector(foo))

类的底层构造
struct objc_class {
 Class isa OBJC_ISA_AVAILABILITY; //isa指针   
#if !__OBJC2__ Class 
super_class OBJC2_UNAVAILABLE; // 父类 
const char *name OBJC2_UNAVAILABLE; // 类名 
long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0 
long info OBJC2_UNAVAILABLE; // 类信息
long instance_size OBJC2_UNAVAILABLE; // 类占据的内存大小 
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 成员变量链表 
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法链表 
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法缓存列表 
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表
 #endif
 } OBJC2_UNAVAILABLE;
objc在向一个对象发送消息时,runtime库会根据对象的isa指针找到该对象实际所属的类,然后在该类中的方法列表以及其父类方法列表中寻找方法运行。如果在层层的寻找中,均未找到方法的实现,就会走消息转发机制,如果我们没有实现相应方法,就是会抛出unrecognized selector sent to XXX的异常,导致程序崩溃。
消息转发机制提供了三次机会去拯救程序
1、利用runtime重定义方法
voidrun (idself,SEL_cmd){
   
NSLog(@"person run");
}
//增加方法
+(
BOOL)resolveInstanceMethod:(SEL)sel{
   
class_addMethod(self, sel, (IMP)run,"v@:");
   
return YES;
}
resolveInstanceMethod中返回YES,程序就会认为我们已经重新实现了该方法,会重新调用该方法。
2、快速转发
//重定向方法
-(
id)forwardingTargetForSelector:(SEL)aSelector{
   
return [[RunPersonalloc]init];
}
在该方法中,返回一个处理该消息的实例,这里不能返回自己的类对象,会死循环。
3、普通转发
-(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector{
   return [NSMethodSignaturesignatureWithObjCTypes:"v@:"];
}
-(
void)forwardInvocation:(NSInvocation*)anInvocation{
   
SEL sel = [anInvocation selector];
   
RunPerson* runPerson = [[RunPersonalloc]init];
   
if ([runPerson respondsToSelector:sel]) {
        [anInvocation
invokeWithTarget:runPerson];
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值