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:&***];
}