objc_msgSend()消息发送的三大阶段,第三阶段就是消息转发

调用Person对象的test方法

Person *p = [[Person alloc] init];
[p test];

消息转发,分为两种情况

第一种,直接转发给其他对象

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

第二种情况,如果对象没有实现forwardingTargetForSelector方法,通过方法签名转发给其他对象,或者自己处理

// 以下两个方法是成对出现,方法签名如果返回为nil,那么`forwardInvocation`也不会调用了
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
    if (aSelector == @selector(test)) {
        return [NSMethodSignature signatureWithObjCTypes:"v16@0:8"];
    }
    return [super methodSignatureForSelector:aSelector];
}
// NSInvocation 封装了方法调用,包括: 方法调用者,方法名,方法参数
// anInvocation.target 方法调用者
// anInvocation.selector 方法名
// [anInvocation getArgument:NULL atIndex:0] 方法参数
- (void)forwardInvocation:(NSInvocation *)anInvocation{
//    anInvocation.target = [[Car alloc] init]; 这样写有问题,对象直接就销毁了,会崩溃
//    [anInvocation invoke];
    [anInvocation invokeWithTarget:[[Car alloc] init]];
}