面试总结 - OC方法调用流程

OC中的方法调用,其实都是转换为objc_msgSend函数的调用
objc_msgSend的执行流程可以分为3大阶段

1.消息发送

receiver是否为nil,是->退出,否->从receiverClass的cache中查找方法,找到方法->调用方法结束查找,没找到->从receiverClass的class_rw_t中查找方法,找到方法->调用方法,结束查找,并将方法缓存到receiverClass的cache中,没找到->从superClass的cache中查找方法,找到方法->调用方法,结束查找,并将方法缓存到receiverClass的cache中,没找到->从superClass的class_rw_t中查找方法,找到方法->调用方法,结束查找并将方法缓存到receiverClass的cache中,没找到->上层是否还有superClass,是->从superClass的cache中查找方法…,否->动态方法解析

2.动态方法解析

是否曾经有动态解析,否->调用+resolveInstanceMethod:或者+resolveClassMethod:方法来动态解析方法,并标记为已经动态解析,动态解析过后,会重新走“消息发送”的流程,从receiverClass的cache中查找方法 这一步开始执行,是->消息转发

void c_other(id self, SEL _cmd){}
- (void)test{}
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
  if(sel == @seletor(test)){
      class_addMethod(self, sel, (IMP)c_other, “v16@0:8);
      //resolveClassMethod:第一个参数objc_getClass(self)
      // Method method = class_getInstanceMethod(self, @selector(test));
      // class_addMethod(self, sel, method_getImplementation(method), method_getTypeEncoding(method));
     return  YES;
 }
}
3.消息转发

调用forwardingTargetForSelector:方法,返回值不为nil->objc_msgSend(返回值,SEL)
返回值为nil->调用methodSignatureForSelector:方法,返回值不为nil->调用forwardInvocation:方法
返回值为nil->调用doesNotRecognizeSelector方法。
**开发者可以在forwardingInvocation:方法中自定义任何逻辑,以上方法都有对象方法,类方法两个版本±

- (id)forwardingTargetForSelector:(SEL)aSelector
{
  if(aSelector == @selector(test)){
    return [[NSObject alloc]init];
  }
   return [super forwardingTargetForSelector:aSelector];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
  if(aSelector == @selector(test)){
    return [[NSObject alloc]init];
  }
   return [super methodSignatureForSelector:aSelector];
}
- (void)forwardingInvocation:(NSInvocation *)anInvocation{
   参数顺序:receiver,selector,tother arguments
   anInvocation.target
   anInvocation.selector
   [anInvocation invokeWithTarget:***];
   [anInvocation getArgument:&*** atIndex:2];
   [anInvocation getReturnValue:&***];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值