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]];
}