面试总结 - 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:&***];
}
发布了218 篇原创文章 · 获赞 19 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/songzhuo1991/article/details/104883308