iOS Message Forward
//
// Person.m
// TestMsgForward
//
// Created by Sunhy on 2017/8/14.
// Copyright © 2017年 Sunhy. All rights reserved.
// http://www.cocoachina.com/ios/20150604/12013.html
//
#import "Person.h"
#import "Animal.h"
#import "objc/runtime.h"
@implementation Person
//
//- (void)run {
//
//}
#pragma mark - **************** 动态实现
//+ (BOOL)resolveClassMethod:(SEL)aSEL {
// if (aSEL == @selector(run))
// {
// class_addMethod(object_getClass([self class]), aSEL, (IMP) dynamicMethodIMP, "v@:");
// return YES;
// }
// return [super resolveInstanceMethod:aSEL];
//}
//
//+ (BOOL) resolveInstanceMethod:(SEL)aSEL
//{
// if (aSEL == @selector(run))
// {
// class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "v@:");
// return YES;
// }
// return [super resolveInstanceMethod:aSEL];
//}
void dynamicMethodIMP(id self, SEL _cmd)
{
NSLog(@"动态实现实例方法 run");
}
#pragma mark - **************** 动态提供响应者
//- (id)forwardingTargetForSelector:(SEL)aSelector {
// if (aSelector == @selector(run)) {
// return [[Animal alloc] init];
// }
// return nil;
//}
#pragma mark - **************** 完整消息转发
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
if (sel == @selector(run)) {
// v:表示void @表示调用者self :表示_cmd
return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
return nil;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
// 关于生成签名的类型"v@:"解释一下。每一个方法会默认隐藏两个参数,self、_cmd,self代表方法调用者,_cmd代表这个方法的SEL,签名类型就是用来描述这个方法的返回值、参数的,v代表返回值为void,@表示self,:表示_cmd。
SEL aSelector = [invocation selector];
Animal *ani = [[Animal alloc] init];
if ([ani respondsToSelector:aSelector])
[invocation invokeWithTarget:ani];
else
[super forwardInvocation:invocation];
}
@end